mirror of https://github.com/PCSX2/pcsx2.git
USB: clang-format
This commit is contained in:
parent
56e96a8ff9
commit
0c43fa92e5
|
@ -26,34 +26,37 @@
|
|||
#include "shared/shared.h"
|
||||
#include "deviceproxy.h"
|
||||
|
||||
#define PSXCLK 36864000 /* 36.864 Mhz */
|
||||
#define PSXCLK 36864000 /* 36.864 Mhz */
|
||||
|
||||
OHCIState *qemu_ohci = NULL;
|
||||
USBDevice *usb_device[2] = { NULL };
|
||||
OHCIState* qemu_ohci = NULL;
|
||||
USBDevice* usb_device[2] = {NULL};
|
||||
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;
|
||||
} usb_packet;
|
||||
} USBfreezeData;
|
||||
|
||||
u8 *ram = 0;
|
||||
FILE *usbLog;
|
||||
u8* ram = 0;
|
||||
FILE* usbLog;
|
||||
int64_t usb_frame_time;
|
||||
int64_t usb_bit_time;
|
||||
|
||||
|
@ -66,11 +69,12 @@ HWND gsWnd = nullptr;
|
|||
#include "gtk.h"
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/X.h>
|
||||
Display *g_GSdsp;
|
||||
Display* g_GSdsp;
|
||||
Window g_GSwin;
|
||||
#endif
|
||||
|
||||
Config::Config(): Log(0)
|
||||
Config::Config()
|
||||
: Log(0)
|
||||
{
|
||||
memset(&WheelType, 0, sizeof(WheelType));
|
||||
}
|
||||
|
@ -78,19 +82,20 @@ Config::Config(): Log(0)
|
|||
//Simpler to reset and reattach after USBclose/USBopen
|
||||
void Reset()
|
||||
{
|
||||
if(qemu_ohci)
|
||||
if (qemu_ohci)
|
||||
ohci_hard_reset(qemu_ohci);
|
||||
}
|
||||
|
||||
void DestroyDevices()
|
||||
{
|
||||
for (int i=0; i<2; i++)
|
||||
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;
|
||||
}
|
||||
else if(usb_device[i])
|
||||
else if (usb_device[i])
|
||||
usb_device[i]->klass.unrealize(usb_device[i]);
|
||||
|
||||
usb_device[i] = nullptr;
|
||||
|
@ -99,7 +104,7 @@ void DestroyDevices()
|
|||
|
||||
USBDevice* CreateDevice(DeviceType index, int port)
|
||||
{
|
||||
DeviceProxyBase *devProxy;
|
||||
DeviceProxyBase* devProxy;
|
||||
USBDevice* device = nullptr;
|
||||
|
||||
if (index == DEVTYPE_NONE)
|
||||
|
@ -111,22 +116,24 @@ 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;
|
||||
}
|
||||
|
||||
//TODO re-do sneaky attach
|
||||
void USBAttach(int port, USBDevice *dev, bool sneaky = false)
|
||||
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;
|
||||
USBDevice* tmp = qemu_ohci->rhport[port].port.dev;
|
||||
if (tmp)
|
||||
{
|
||||
if (!sneaky)
|
||||
usb_detach (&qemu_ohci->rhport[port].port);
|
||||
usb_detach(&qemu_ohci->rhport[port].port);
|
||||
tmp->klass.unrealize(tmp);
|
||||
}
|
||||
|
||||
|
@ -134,13 +141,13 @@ void USBAttach(int port, USBDevice *dev, bool sneaky = false)
|
|||
if (dev)
|
||||
{
|
||||
dev->attached = true;
|
||||
usb_attach (&qemu_ohci->rhport[port].port); //.ops->attach(&(qemu_ohci->rhport[port].port));
|
||||
usb_attach(&qemu_ohci->rhport[port].port); //.ops->attach(&(qemu_ohci->rhport[port].port));
|
||||
}
|
||||
}
|
||||
|
||||
USBDevice* CreateDevice(const std::string& name, int port)
|
||||
{
|
||||
DeviceProxyBase *devProxy;
|
||||
DeviceProxyBase* devProxy;
|
||||
USBDevice* device = nullptr;
|
||||
|
||||
if (!name.empty())
|
||||
|
@ -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,17 +168,19 @@ 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++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
usb_device[i] = CreateDevice(conf.Port[i], i);
|
||||
USBAttach(i, usb_device[i]);
|
||||
}
|
||||
}
|
||||
|
||||
s32 USBinit() {
|
||||
s32 USBinit()
|
||||
{
|
||||
OSDebugOut(TEXT("USBinit\n"));
|
||||
|
||||
RegisterDevice::Register();
|
||||
|
@ -178,13 +188,14 @@ s32 USBinit() {
|
|||
|
||||
if (conf.Log && !usbLog)
|
||||
{
|
||||
usbLog = wfopen(LogDir.c_str(), "wb");// L"wb,ccs=UNICODE");
|
||||
usbLog = wfopen(LogDir.c_str(), "wb"); // L"wb,ccs=UNICODE");
|
||||
//if(usbLog) setvbuf(usbLog, NULL, _IONBF, 0);
|
||||
USB_LOG("USBinit\n");
|
||||
}
|
||||
|
||||
qemu_ohci = ohci_create(0x1f801600,2);
|
||||
if(!qemu_ohci) return 1;
|
||||
qemu_ohci = ohci_create(0x1f801600, 2);
|
||||
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();
|
||||
|
@ -202,15 +214,17 @@ void USBshutdown() {
|
|||
|
||||
ram = 0;
|
||||
|
||||
//#ifdef _DEBUG
|
||||
if (conf.Log && usbLog) {
|
||||
//#ifdef _DEBUG
|
||||
if (conf.Log && usbLog)
|
||||
{
|
||||
fclose(usbLog);
|
||||
usbLog = nullptr;
|
||||
}
|
||||
//#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
s32 USBopen(void *pDsp) {
|
||||
s32 USBopen(void* pDsp)
|
||||
{
|
||||
|
||||
if (conf.Log && !usbLog)
|
||||
{
|
||||
|
@ -223,31 +237,34 @@ s32 USBopen(void *pDsp) {
|
|||
|
||||
#if _WIN32
|
||||
|
||||
HWND hWnd=(HWND)pDsp;
|
||||
HWND hWnd = (HWND)pDsp;
|
||||
//HWND hWnd=(HWND)((uptr*)pDsp)[0];
|
||||
|
||||
if (!IsWindow (hWnd))
|
||||
if (!IsWindow(hWnd))
|
||||
hWnd = *(HWND*)hWnd;
|
||||
|
||||
if (!IsWindow (hWnd))
|
||||
if (!IsWindow(hWnd))
|
||||
hWnd = NULL;
|
||||
else
|
||||
{
|
||||
while (GetWindowLong (hWnd, GWL_STYLE) & WS_CHILD)
|
||||
hWnd = GetParent (hWnd);
|
||||
while (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
||||
hWnd = GetParent(hWnd);
|
||||
}
|
||||
gsWnd = hWnd;
|
||||
pDsp = gsWnd;
|
||||
#else
|
||||
|
||||
g_GSdsp = (Display *)((uptr*)pDsp)[0];
|
||||
g_GSdsp = (Display*)((uptr*)pDsp)[0];
|
||||
g_GSwin = (Window)((uptr*)pDsp)[1];
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -258,75 +275,83 @@ s32 USBopen(void *pDsp) {
|
|||
}
|
||||
|
||||
//TODO Pass pDsp to open probably so dinput can bind to this HWND
|
||||
if(usb_device[0] && usb_device[0]->klass.open)
|
||||
usb_device[0]->klass.open(usb_device[0]/*, pDsp*/);
|
||||
if (usb_device[0] && usb_device[0]->klass.open)
|
||||
usb_device[0]->klass.open(usb_device[0] /*, pDsp*/);
|
||||
|
||||
if(usb_device[1] && usb_device[1]->klass.open)
|
||||
usb_device[1]->klass.open(usb_device[1]/*, pDsp*/);
|
||||
if (usb_device[1] && usb_device[1]->klass.open)
|
||||
usb_device[1]->klass.open(usb_device[1] /*, pDsp*/);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBclose() {
|
||||
void USBclose()
|
||||
{
|
||||
OSDebugOut(TEXT("USBclose\n"));
|
||||
|
||||
if(usb_device[0] && usb_device[0]->klass.close)
|
||||
if (usb_device[0] && usb_device[0]->klass.close)
|
||||
usb_device[0]->klass.close(usb_device[0]);
|
||||
|
||||
if(usb_device[1] && usb_device[1]->klass.close)
|
||||
if (usb_device[1] && usb_device[1]->klass.close)
|
||||
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);
|
||||
hard = ohci_mem_read(qemu_ohci, addr);
|
||||
|
||||
USB_LOG("* Known 32bit read at address %lx: %lx\n", addr, hard);
|
||||
|
||||
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);
|
||||
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) {
|
||||
USBfreezeData usbd = { 0 };
|
||||
s32 USBfreeze(int mode, freezeData* data)
|
||||
{
|
||||
USBfreezeData usbd = {0};
|
||||
|
||||
//TODO FREEZE_SIZE mismatch causes loading to fail in PCSX2 beforehand
|
||||
if (mode == FREEZE_LOAD)
|
||||
{
|
||||
if((long unsigned int)data->size < sizeof(USBfreezeData))
|
||||
if ((long unsigned int)data->size < sizeof(USBfreezeData))
|
||||
{
|
||||
SysMessage(TEXT("ERROR: Unable to load freeze data! Got %d bytes, expected >= %d.\n"), data->size, sizeof(USBfreezeData));
|
||||
return -1;
|
||||
|
@ -335,7 +360,7 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
usbd = *(USBfreezeData*)data->data;
|
||||
usbd.freezeID[10] = 0;
|
||||
|
||||
if( strcmp(usbd.freezeID, USBfreezeID) != 0)
|
||||
if (strcmp(usbd.freezeID, USBfreezeID) != 0)
|
||||
{
|
||||
SysMessage(TEXT("ERROR: Unable to load freeze data! Found ID '%") TEXT(SFMTs) TEXT("', expected ID '%") TEXT(SFMTs) TEXT("'.\n"), usbd.freezeID, USBfreezeID);
|
||||
return -1;
|
||||
|
@ -345,7 +370,7 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
//clocks = usbd.cycles;
|
||||
//remaining = usbd.remaining;
|
||||
|
||||
for(uint32_t i=0; i< qemu_ohci->num_ports; i++)
|
||||
for (uint32_t i = 0; i < qemu_ohci->num_ports; i++)
|
||||
{
|
||||
usbd.t.rhport[i].port.opaque = qemu_ohci;
|
||||
usbd.t.rhport[i].port.ops = qemu_ohci->rhport[i].port.ops;
|
||||
|
@ -353,13 +378,13 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
}
|
||||
*qemu_ohci = usbd.t;
|
||||
|
||||
s8 *ptr = data->data + sizeof(USBfreezeData);
|
||||
s8* ptr = data->data + sizeof(USBfreezeData);
|
||||
// Load the state of the attached devices
|
||||
if ((long unsigned int)data->size != sizeof(USBfreezeData) + usbd.device[0].size + usbd.device[1].size + 8192)
|
||||
return -1;
|
||||
|
||||
RegisterDevice& regInst = RegisterDevice::instance();
|
||||
for (int i=0; i<2; i++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto index = regInst.Index(conf.Port[i]);
|
||||
auto proxy = regInst.Device(index);
|
||||
|
@ -369,7 +394,7 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
if (usbd.device[i].index != index)
|
||||
{
|
||||
index = usbd.device[i].index;
|
||||
USBDevice *dev = qemu_ohci->rhport[i].port.dev;
|
||||
USBDevice* dev = qemu_ohci->rhport[i].port.dev;
|
||||
qemu_ohci->rhport[i].port.dev = nullptr;
|
||||
|
||||
if (dev)
|
||||
|
@ -387,7 +412,7 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
{
|
||||
if (proxy->Freeze(FREEZE_SIZE, usb_device[i], nullptr) != (s32)usbd.device[i].size)
|
||||
{
|
||||
SysMessage(TEXT("Port %d: device's freeze size doesn't match.\n"), 1+(1-i));
|
||||
SysMessage(TEXT("Port %d: device's freeze size doesn't match.\n"), 1 + (1 - i));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -409,19 +434,20 @@ 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]);
|
||||
}
|
||||
|
||||
proxy->Freeze(FREEZE_LOAD, usb_device[i], ptr);
|
||||
//TODO reset port if save state's and configured wheel types are different
|
||||
usb_detach (&qemu_ohci->rhport[i].port);
|
||||
usb_attach (&qemu_ohci->rhport[i].port);
|
||||
usb_detach(&qemu_ohci->rhport[i].port);
|
||||
usb_attach(&qemu_ohci->rhport[i].port);
|
||||
}
|
||||
else if (!proxy && index != DEVTYPE_NONE)
|
||||
{
|
||||
SysMessage(TEXT("Port %d: unknown device.\nPlugin is probably too old for this save.\n"), 1+(1-i));
|
||||
SysMessage(TEXT("Port %d: unknown device.\nPlugin is probably too old for this save.\n"), 1 + (1 - i));
|
||||
return -1;
|
||||
}
|
||||
ptr += usbd.device[i].size;
|
||||
|
@ -435,10 +461,10 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
|
||||
if (usb_device[dev_index])
|
||||
{
|
||||
USBPacket *p = &qemu_ohci->usb_packet;
|
||||
USBPacket* p = &qemu_ohci->usb_packet;
|
||||
p->actual_length = usbd.usb_packet.data_size;
|
||||
|
||||
QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
|
||||
QEMUIOVector* iov = p->combined ? &p->combined->iov : &p->iov;
|
||||
iov_from_buf(iov->iov, iov->niov, 0, ptr, p->actual_length);
|
||||
|
||||
if (usbd.usb_packet.ep.pid == USB_TOKEN_SETUP)
|
||||
|
@ -448,18 +474,16 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
}
|
||||
else
|
||||
{
|
||||
USBEndpoint *eps = nullptr;
|
||||
USBEndpoint* eps = nullptr;
|
||||
if (usbd.usb_packet.ep.pid == USB_TOKEN_IN)
|
||||
eps = usb_device[dev_index]->ep_in;
|
||||
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;
|
||||
|
@ -476,11 +500,11 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
//TODO straight copying of structs can break cross-platform/cross-compiler save states 'cause padding 'n' stuff
|
||||
else if (mode == FREEZE_SAVE)
|
||||
{
|
||||
memset(data->data, 0, data->size);//maybe it already is...
|
||||
memset(data->data, 0, data->size); //maybe it already is...
|
||||
RegisterDevice& regInst = RegisterDevice::instance();
|
||||
usbd.usb_packet.dev_index = -1;
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
//TODO check that current created usb device and conf.Port[n] are the same
|
||||
auto index = regInst.Index(conf.Port[i]);
|
||||
|
@ -499,10 +523,10 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
strncpy(usbd.freezeID, USBfreezeID, strlen(usbd.freezeID));
|
||||
usbd.t = *qemu_ohci;
|
||||
usbd.usb_packet.ep = qemu_ohci->usb_packet.ep ? *qemu_ohci->usb_packet.ep : USBEndpoint{0};
|
||||
usbd.t.usb_packet.iov = { };
|
||||
usbd.t.usb_packet.iov = {};
|
||||
usbd.t.usb_packet.ep = nullptr;
|
||||
|
||||
for(uint32_t i=0; i< qemu_ohci->num_ports; i++)
|
||||
for (uint32_t i = 0; i < qemu_ohci->num_ports; i++)
|
||||
{
|
||||
usbd.t.rhport[i].port.opaque = nullptr;
|
||||
usbd.t.rhport[i].port.ops = nullptr;
|
||||
|
@ -512,10 +536,10 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
usbd.cycles = clocks;
|
||||
usbd.remaining = remaining;
|
||||
|
||||
s8 *ptr = data->data + sizeof(USBfreezeData);
|
||||
s8* ptr = data->data + sizeof(USBfreezeData);
|
||||
|
||||
// Save the state of the attached devices
|
||||
for (int i=0; i<2; i++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto proxy = regInst.Device(conf.Port[i]);
|
||||
if (proxy && usbd.device[i].size)
|
||||
|
@ -524,15 +548,15 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
if (usb_device[i])
|
||||
usbd.device[i].dev = *usb_device[i];
|
||||
|
||||
memset (&usbd.device[i].dev.klass, 0, sizeof(USBDeviceClass));
|
||||
memset(&usbd.device[i].dev.klass, 0, sizeof(USBDeviceClass));
|
||||
}
|
||||
|
||||
ptr += usbd.device[i].size;
|
||||
}
|
||||
|
||||
USBPacket *p = &qemu_ohci->usb_packet;
|
||||
USBPacket* p = &qemu_ohci->usb_packet;
|
||||
usbd.usb_packet.data_size = p->actual_length;
|
||||
QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
|
||||
QEMUIOVector* iov = p->combined ? &p->combined->iov : &p->iov;
|
||||
iov_to_buf(iov->iov, iov->niov, 0, ptr, p->actual_length);
|
||||
|
||||
*(USBfreezeData*)data->data = usbd;
|
||||
|
@ -541,7 +565,7 @@ s32 USBfreeze(int mode, freezeData *data) {
|
|||
{
|
||||
RegisterDevice& regInst = RegisterDevice::instance();
|
||||
data->size = sizeof(USBfreezeData);
|
||||
for (int i=0; i<2; i++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
//TODO check that current created usb device and conf.Port[n] are the same
|
||||
auto proxy = regInst.Device(conf.Port[i]);
|
||||
|
@ -551,8 +575,9 @@ 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) {
|
||||
data->size += 8192; // qemu_ohci->usb_packet.actual_length;
|
||||
if (qemu_ohci->usb_packet.actual_length > 8192)
|
||||
{
|
||||
fprintf(stderr, "Saving failed! USB packet is larger than 8K, try again later.\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -565,12 +590,12 @@ void USBasync(u32 cycles)
|
|||
{
|
||||
remaining += cycles;
|
||||
clocks += remaining;
|
||||
if(qemu_ohci->eof_timer>0)
|
||||
if (qemu_ohci->eof_timer > 0)
|
||||
{
|
||||
while((uint64_t)remaining>=qemu_ohci->eof_timer)
|
||||
while ((uint64_t)remaining >= qemu_ohci->eof_timer)
|
||||
{
|
||||
remaining-=qemu_ohci->eof_timer;
|
||||
qemu_ohci->eof_timer=0;
|
||||
remaining -= qemu_ohci->eof_timer;
|
||||
qemu_ohci->eof_timer = 0;
|
||||
ohci_frame_boundary(qemu_ohci);
|
||||
|
||||
/*
|
||||
|
@ -581,10 +606,10 @@ void USBasync(u32 cycles)
|
|||
if (!qemu_ohci->eof_timer)
|
||||
break;
|
||||
}
|
||||
if((remaining>0)&&(qemu_ohci->eof_timer>0))
|
||||
if ((remaining > 0) && (qemu_ohci->eof_timer > 0))
|
||||
{
|
||||
s64 m = qemu_ohci->eof_timer;
|
||||
if(remaining < m)
|
||||
if (remaining < m)
|
||||
m = remaining;
|
||||
qemu_ohci->eof_timer -= m;
|
||||
remaining -= m;
|
||||
|
@ -596,11 +621,11 @@ void USBasync(u32 cycles)
|
|||
//}
|
||||
}
|
||||
|
||||
int cpu_physical_memory_rw(u32 addr, u8 *buf, size_t len, int is_write)
|
||||
int cpu_physical_memory_rw(u32 addr, u8* buf, size_t len, int is_write)
|
||||
{
|
||||
//OSDebugOut(TEXT("%s addr %08X, len %d\n"), is_write ? TEXT("write") : TEXT("read "), addr, len);
|
||||
// invalid address, reset and try again
|
||||
if (addr+len >= 0x200000)
|
||||
if (addr + len >= 0x200000)
|
||||
{
|
||||
OSDebugOut(TEXT("invalid address, soft resetting ohci.\n"));
|
||||
if (qemu_ohci)
|
||||
|
@ -608,10 +633,10 @@ int cpu_physical_memory_rw(u32 addr, u8 *buf, size_t len, int is_write)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(is_write)
|
||||
memcpy(&(ram[addr]),buf,len);
|
||||
if (is_write)
|
||||
memcpy(&(ram[addr]), buf, len);
|
||||
else
|
||||
memcpy(buf,&(ram[addr]),len);
|
||||
memcpy(buf, &(ram[addr]), len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
// ---------------------------------------------------------------------
|
||||
#define USBdefs
|
||||
|
||||
extern u8 *ram;
|
||||
extern u8* ram;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
@ -39,29 +39,28 @@ s32 USBinit();
|
|||
void USBasync(u32 cycles);
|
||||
void USBshutdown();
|
||||
void USBclose();
|
||||
s32 USBopen(void *pDsp);
|
||||
s32 USBfreeze(int mode, freezeData *data);
|
||||
s32 USBopen(void* pDsp);
|
||||
s32 USBfreeze(int mode, freezeData* data);
|
||||
|
||||
u8 USBread8(u32 addr);
|
||||
u16 USBread16(u32 addr);
|
||||
u32 USBread32(u32 addr);
|
||||
void USBwrite8(u32 addr, u8 value);
|
||||
void USBwrite8(u32 addr, u8 value);
|
||||
void USBwrite16(u32 addr, u16 value);
|
||||
void USBwrite32(u32 addr, u32 value);
|
||||
|
||||
|
||||
void USBsetRAM(void *mem);
|
||||
void USBsetRAM(void* mem);
|
||||
|
||||
extern FILE *usbLog;
|
||||
extern FILE* usbLog;
|
||||
s64 get_clock();
|
||||
|
||||
/* usb-pad-raw.cpp */
|
||||
#if _WIN32
|
||||
extern HWND gsWnd;
|
||||
# if defined(BUILD_RAW)
|
||||
#if defined(BUILD_RAW)
|
||||
extern HWND msgWindow;
|
||||
int InitWindow(HWND);
|
||||
void UninitWindow();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,17 +103,19 @@ 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();
|
||||
CheckDlgButton(hW, IDC_LOGGING, conf.Log);
|
||||
//Selected emulated devices.
|
||||
SendDlgItemMessageA(hW, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)"None");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO2, CB_ADDSTRING, 0, (LPARAM)"None");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM) "None");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO2, CB_ADDSTRING, 0, (LPARAM) "None");
|
||||
|
||||
{
|
||||
auto& rd = RegisterDevice::instance();
|
||||
|
@ -136,16 +140,16 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
PopulateAPIs(hW, 1);
|
||||
}
|
||||
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM)"Driving Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM)"Driving Force Pro");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM)"Driving Force Pro (rev11.02)");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM)"GT Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM) "Driving Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM) "Driving Force Pro");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM) "Driving Force Pro (rev11.02)");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE1, CB_ADDSTRING, 0, (LPARAM) "GT Force");
|
||||
SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE1, CB_SETCURSEL, conf.WheelType[PLAYER_ONE_PORT], 0);
|
||||
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM)"Driving Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM)"Driving Force Pro");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM)"Driving Force Pro (rev11.02)");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM)"GT Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM) "Driving Force");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM) "Driving Force Pro");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM) "Driving Force Pro (rev11.02)");
|
||||
SendDlgItemMessageA(hW, IDC_COMBO_WHEEL_TYPE2, CB_ADDSTRING, 0, (LPARAM) "GT Force");
|
||||
SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE2, CB_SETCURSEL, conf.WheelType[PLAYER_TWO_PORT], 0);
|
||||
|
||||
return TRUE;
|
||||
|
@ -153,73 +157,75 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_COMMAND:
|
||||
switch (HIWORD(wParam))
|
||||
{
|
||||
case CBN_SELCHANGE:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_COMBO_API1:
|
||||
case IDC_COMBO_API2:
|
||||
port = (LOWORD(wParam) == IDC_COMBO_API1) ? 1 : 0;
|
||||
SelChangedAPI(hW, port);
|
||||
break;
|
||||
case IDC_COMBO1:
|
||||
case IDC_COMBO2:
|
||||
port = (LOWORD(wParam) == IDC_COMBO1) ? 1 : 0;
|
||||
PopulateAPIs(hW, port);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BN_CLICKED:
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_CONFIGURE1:
|
||||
case IDC_CONFIGURE2:
|
||||
{
|
||||
LRESULT devtype, apitype;
|
||||
port = (LOWORD(wParam) == IDC_CONFIGURE1) ? 1 : 0;
|
||||
devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1 : IDC_COMBO2, CB_GETCURSEL, 0, 0);
|
||||
apitype = SendDlgItemMessage(hW, port ? IDC_COMBO_API1 : IDC_COMBO_API2, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (devtype > 0)
|
||||
case CBN_SELCHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
devtype--;
|
||||
auto device = RegisterDevice::instance().Device(devtype);
|
||||
if (device)
|
||||
case IDC_COMBO_API1:
|
||||
case IDC_COMBO_API2:
|
||||
port = (LOWORD(wParam) == IDC_COMBO_API1) ? 1 : 0;
|
||||
SelChangedAPI(hW, port);
|
||||
break;
|
||||
case IDC_COMBO1:
|
||||
case IDC_COMBO2:
|
||||
port = (LOWORD(wParam) == IDC_COMBO1) ? 1 : 0;
|
||||
PopulateAPIs(hW, port);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BN_CLICKED:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_CONFIGURE1:
|
||||
case IDC_CONFIGURE2:
|
||||
{
|
||||
auto list = device->ListAPIs();
|
||||
auto it = list.begin();
|
||||
std::advance(it, apitype);
|
||||
if (it == list.end())
|
||||
break;
|
||||
std::string api = *it;
|
||||
Win32Handles handles(hInst, hW);
|
||||
if (device->Configure(port, api, &handles) == RESULT_FAILED)
|
||||
SysMessage(TEXT("Some settings may not have been saved!\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, TRUE);
|
||||
return TRUE;
|
||||
case IDOK:
|
||||
conf.Log = IsDlgButtonChecked(hW, IDC_LOGGING);
|
||||
{
|
||||
auto& regInst = RegisterDevice::instance();
|
||||
int i;
|
||||
//device type
|
||||
i = SendDlgItemMessage(hW, IDC_COMBO1, CB_GETCURSEL, 0, 0);
|
||||
conf.Port[1] = regInst.Name(i - 1);
|
||||
i = SendDlgItemMessage(hW, IDC_COMBO2, CB_GETCURSEL, 0, 0);
|
||||
conf.Port[0] = regInst.Name(i - 1);
|
||||
}
|
||||
//wheel type
|
||||
conf.WheelType[PLAYER_ONE_PORT] = SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE1, CB_GETCURSEL, 0, 0);
|
||||
conf.WheelType[PLAYER_TWO_PORT] = SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE2, CB_GETCURSEL, 0, 0);
|
||||
LRESULT devtype, apitype;
|
||||
port = (LOWORD(wParam) == IDC_CONFIGURE1) ? 1 : 0;
|
||||
devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1 : IDC_COMBO2, CB_GETCURSEL, 0, 0);
|
||||
apitype = SendDlgItemMessage(hW, port ? IDC_COMBO_API1 : IDC_COMBO_API2, CB_GETCURSEL, 0, 0);
|
||||
|
||||
SaveConfig();
|
||||
CreateDevices();
|
||||
EndDialog(hW, RESULT_OK);
|
||||
configChanged = true;
|
||||
return TRUE;
|
||||
}
|
||||
if (devtype > 0)
|
||||
{
|
||||
devtype--;
|
||||
auto device = RegisterDevice::instance().Device(devtype);
|
||||
if (device)
|
||||
{
|
||||
auto list = device->ListAPIs();
|
||||
auto it = list.begin();
|
||||
std::advance(it, apitype);
|
||||
if (it == list.end())
|
||||
break;
|
||||
std::string api = *it;
|
||||
Win32Handles handles(hInst, hW);
|
||||
if (device->Configure(port, api, &handles) == RESULT_FAILED)
|
||||
SysMessage(TEXT("Some settings may not have been saved!\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, TRUE);
|
||||
return TRUE;
|
||||
case IDOK:
|
||||
conf.Log = IsDlgButtonChecked(hW, IDC_LOGGING);
|
||||
{
|
||||
auto& regInst = RegisterDevice::instance();
|
||||
int i;
|
||||
//device type
|
||||
i = SendDlgItemMessage(hW, IDC_COMBO1, CB_GETCURSEL, 0, 0);
|
||||
conf.Port[1] = regInst.Name(i - 1);
|
||||
i = SendDlgItemMessage(hW, IDC_COMBO2, CB_GETCURSEL, 0, 0);
|
||||
conf.Port[0] = regInst.Name(i - 1);
|
||||
}
|
||||
//wheel type
|
||||
conf.WheelType[PLAYER_ONE_PORT] = SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE1, CB_GETCURSEL, 0, 0);
|
||||
conf.WheelType[PLAYER_TWO_PORT] = SendDlgItemMessage(hW, IDC_COMBO_WHEEL_TYPE2, CB_GETCURSEL, 0, 0);
|
||||
|
||||
SaveConfig();
|
||||
CreateDevices();
|
||||
EndDialog(hW, RESULT_OK);
|
||||
configChanged = true;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,26 +252,30 @@ 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,
|
||||
MAKEINTRESOURCE(IDD_CONFIG),
|
||||
GetActiveWindow(),
|
||||
(DLGPROC)ConfigureDlgProc);
|
||||
RegisterDevice::Register();
|
||||
DialogBox(hInst,
|
||||
MAKEINTRESOURCE(IDD_CONFIG),
|
||||
GetActiveWindow(),
|
||||
(DLGPROC)ConfigureDlgProc);
|
||||
paused_core.AllowResume();
|
||||
}
|
||||
|
||||
EXPORT_C_(void) USBabout() {
|
||||
DialogBox(hInst,
|
||||
MAKEINTRESOURCE(IDD_ABOUT),
|
||||
GetActiveWindow(),
|
||||
(DLGPROC)AboutDlgProc);
|
||||
EXPORT_C_(void)
|
||||
USBabout()
|
||||
{
|
||||
DialogBox(hInst,
|
||||
MAKEINTRESOURCE(IDD_ABOUT),
|
||||
GetActiveWindow(),
|
||||
(DLGPROC)AboutDlgProc);
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HANDLE hModule,
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved) {
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
hInst = (HINSTANCE)hModule;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -21,24 +21,25 @@ 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 {\
|
||||
/*CheckControlTextIsNumber(GetDlgItem(hDlg, nIDDlgItem), bSigned, 0);*/\
|
||||
var = GetDlgItemInt(hDlg, nIDDlgItem, NULL, bSigned);\
|
||||
if (var < min)\
|
||||
var = min;\
|
||||
else if (var > max)\
|
||||
{\
|
||||
var = max;\
|
||||
SetDlgItemInt(hDlg, nIDDlgItem, var, bSigned);\
|
||||
SendMessage(GetDlgItem(hDlg, nIDDlgItem), EM_SETSEL, -2, -2);\
|
||||
}\
|
||||
} while (0)
|
||||
#define CHECKED_SET_MAX_INT(var, hDlg, nIDDlgItem, bSigned, min, max) \
|
||||
do \
|
||||
{ \
|
||||
/*CheckControlTextIsNumber(GetDlgItem(hDlg, nIDDlgItem), bSigned, 0);*/ \
|
||||
var = GetDlgItemInt(hDlg, nIDDlgItem, NULL, bSigned); \
|
||||
if (var < min) \
|
||||
var = min; \
|
||||
else if (var > max) \
|
||||
{ \
|
||||
var = max; \
|
||||
SetDlgItemInt(hDlg, nIDDlgItem, var, bSigned); \
|
||||
SendMessage(GetDlgItem(hDlg, nIDDlgItem), EM_SETSEL, -2, -2); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
|
|
@ -2,43 +2,43 @@
|
|||
// Microsoft Visual C++ generated include file.
|
||||
// Used by USBlinuz.rc
|
||||
//
|
||||
#define IDC_STATIC -1
|
||||
#define IDC_CONFIGURE1 3
|
||||
#define IDC_CONFIGURE2 4
|
||||
#define IDD_CONFDLG 101
|
||||
#define IDD_CONFIG 101
|
||||
#define IDD_ABOUT 103
|
||||
#define IDD_DLGMSD 106
|
||||
#define IDD_DLGWASAPI 107
|
||||
#define IDD_DLG_EYETOY 108
|
||||
#define IDC_NAME 1000
|
||||
#define IDC_LOGGING 1007
|
||||
#define IDC_COMBO1 1008
|
||||
#define IDC_COMBO2 1009
|
||||
#define IDC_LIST1 1010
|
||||
#define IDC_COMBO_API1 1010
|
||||
#define IDC_COMBO3 1010
|
||||
#define IDC_COMBO_FFB 1011
|
||||
#define IDC_COMBO_API2 1011
|
||||
#define IDC_BUTTON1 1012
|
||||
#define IDC_DFP_PASS 1013
|
||||
#define IDC_BUILD_DATE 1014
|
||||
#define IDC_EDIT1 1015
|
||||
#define IDC_COMBO_WHEEL_TYPE1 1037
|
||||
#define IDC_COMBO_WHEEL_TYPE2 1038
|
||||
#define IDC_SLIDER1 1039
|
||||
#define IDC_BUFFER1 1040
|
||||
#define IDC_COMBOMICAPI 1041
|
||||
#define IDC_SLIDER2 1041
|
||||
#define IDC_BUFFER2 1042
|
||||
#define IDC_STATIC -1
|
||||
#define IDC_CONFIGURE1 3
|
||||
#define IDC_CONFIGURE2 4
|
||||
#define IDD_CONFDLG 101
|
||||
#define IDD_CONFIG 101
|
||||
#define IDD_ABOUT 103
|
||||
#define IDD_DLGMSD 106
|
||||
#define IDD_DLGWASAPI 107
|
||||
#define IDD_DLG_EYETOY 108
|
||||
#define IDC_NAME 1000
|
||||
#define IDC_LOGGING 1007
|
||||
#define IDC_COMBO1 1008
|
||||
#define IDC_COMBO2 1009
|
||||
#define IDC_LIST1 1010
|
||||
#define IDC_COMBO_API1 1010
|
||||
#define IDC_COMBO3 1010
|
||||
#define IDC_COMBO_FFB 1011
|
||||
#define IDC_COMBO_API2 1011
|
||||
#define IDC_BUTTON1 1012
|
||||
#define IDC_DFP_PASS 1013
|
||||
#define IDC_BUILD_DATE 1014
|
||||
#define IDC_EDIT1 1015
|
||||
#define IDC_COMBO_WHEEL_TYPE1 1037
|
||||
#define IDC_COMBO_WHEEL_TYPE2 1038
|
||||
#define IDC_SLIDER1 1039
|
||||
#define IDC_BUFFER1 1040
|
||||
#define IDC_COMBOMICAPI 1041
|
||||
#define IDC_SLIDER2 1041
|
||||
#define IDC_BUFFER2 1042
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 109
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1042
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#define _APS_NEXT_RESOURCE_VALUE 109
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1042
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -28,13 +28,13 @@ TSTDSTRING IniPath = TSTDSTRING(TEXT("./inis/")) + iniFile; // default path, jus
|
|||
TSTDSTRING LogDir;
|
||||
CIniFile ciniFile;
|
||||
|
||||
void USBsetSettingsDir( const char* dir )
|
||||
void USBsetSettingsDir(const char* dir)
|
||||
{
|
||||
IniPath = dir;
|
||||
IniPath.append(iniFile);
|
||||
}
|
||||
|
||||
void USBsetLogDir( const char* dir )
|
||||
void USBsetLogDir(const char* dir)
|
||||
{
|
||||
LogDir = dir;
|
||||
}
|
||||
|
@ -49,9 +49,10 @@ std::string GetSelectedAPI(const std::pair<int, std::string>& pair)
|
|||
|
||||
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, TSTDSTRING& value)
|
||||
{
|
||||
CIniKey *key;
|
||||
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;
|
||||
}
|
||||
|
@ -60,14 +61,17 @@ bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TC
|
|||
|
||||
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t& value)
|
||||
{
|
||||
CIniKey *key;
|
||||
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);
|
||||
|
@ -119,7 +126,7 @@ void LoadConfig() {
|
|||
|
||||
auto& instance = RegisterDevice::instance();
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
std::string api;
|
||||
LoadSetting(nullptr, i, conf.Port[i], N_DEVICE_API, api);
|
||||
|
@ -141,7 +148,7 @@ void LoadConfig() {
|
|||
OSDebugOut(_T("API OK\n"));
|
||||
}
|
||||
|
||||
if(api.size())
|
||||
if (api.size())
|
||||
changedAPIs[std::make_pair(i, conf.Port[i])] = api;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,43 +23,44 @@
|
|||
#include "platcompat.h"
|
||||
|
||||
#define RESULT_CANCELED 0
|
||||
#define RESULT_OK 1
|
||||
#define RESULT_FAILED 2
|
||||
#define RESULT_OK 1
|
||||
#define RESULT_FAILED 2
|
||||
|
||||
// freeze modes:
|
||||
#define FREEZE_LOAD 0
|
||||
#define FREEZE_SAVE 1
|
||||
#define FREEZE_SIZE 2
|
||||
#define FREEZE_LOAD 0
|
||||
#define FREEZE_SAVE 1
|
||||
#define FREEZE_SIZE 2
|
||||
|
||||
// Device-level config related defines
|
||||
#define S_DEVICE_API TEXT("Device API")
|
||||
#define S_WHEEL_TYPE TEXT("Wheel type")
|
||||
#define S_DEVICE_PORT0 TEXT("Port 0")
|
||||
#define S_DEVICE_PORT1 TEXT("Port 1")
|
||||
#define S_CONFIG_PATH TEXT("Path")
|
||||
#define S_DEVICE_API TEXT("Device API")
|
||||
#define S_WHEEL_TYPE TEXT("Wheel type")
|
||||
#define S_DEVICE_PORT0 TEXT("Port 0")
|
||||
#define S_DEVICE_PORT1 TEXT("Port 1")
|
||||
#define S_CONFIG_PATH TEXT("Path")
|
||||
|
||||
#define N_DEVICE_API TEXT("device_api")
|
||||
#define N_DEVICES TEXT("devices")
|
||||
#define N_DEVICE TEXT("device")
|
||||
#define N_WHEEL_PT TEXT("wheel_pt")
|
||||
#define N_DEVICE_PORT0 TEXT("port_0")
|
||||
#define N_DEVICE_PORT1 TEXT("port_1")
|
||||
#define N_DEVICE_PORT "port"
|
||||
#define N_WHEEL_TYPE0 TEXT("wheel_type_0")
|
||||
#define N_WHEEL_TYPE1 TEXT("wheel_type_1")
|
||||
#define N_WHEEL_TYPE TEXT("wheel_type")
|
||||
#define N_CONFIG_PATH TEXT("path")
|
||||
#define N_DEVICE_API TEXT("device_api")
|
||||
#define N_DEVICES TEXT("devices")
|
||||
#define N_DEVICE TEXT("device")
|
||||
#define N_WHEEL_PT TEXT("wheel_pt")
|
||||
#define N_DEVICE_PORT0 TEXT("port_0")
|
||||
#define N_DEVICE_PORT1 TEXT("port_1")
|
||||
#define N_DEVICE_PORT "port"
|
||||
#define N_WHEEL_TYPE0 TEXT("wheel_type_0")
|
||||
#define N_WHEEL_TYPE1 TEXT("wheel_type_1")
|
||||
#define N_WHEEL_TYPE TEXT("wheel_type")
|
||||
#define N_CONFIG_PATH TEXT("path")
|
||||
|
||||
#define PLAYER_TWO_PORT 0
|
||||
#define PLAYER_ONE_PORT 1
|
||||
#define USB_PORT PLAYER_ONE_PORT
|
||||
|
||||
struct Config {
|
||||
int Log;
|
||||
std::string Port[2];
|
||||
int WheelType[2];
|
||||
struct Config
|
||||
{
|
||||
int Log;
|
||||
std::string Port[2];
|
||||
int WheelType[2];
|
||||
|
||||
Config();
|
||||
Config();
|
||||
};
|
||||
|
||||
extern Config conf;
|
||||
|
@ -84,10 +85,10 @@ bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TC
|
|||
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, const std::string& value);
|
||||
#endif
|
||||
|
||||
void USBsetSettingsDir( const char* dir );
|
||||
void USBsetLogDir( const char* dir );
|
||||
void USBsetSettingsDir(const char* dir);
|
||||
void USBsetLogDir(const char* dir);
|
||||
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
bool LoadSetting(const char* dev_type, int port, const std::string& key, const TCHAR* name, Type& var)
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -115,7 +116,7 @@ bool LoadSetting(const char* dev_type, int port, const std::string& key, const T
|
|||
return ret;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
bool LoadSetting(const TCHAR* section, const TCHAR* key, Type& var)
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -142,7 +143,7 @@ bool LoadSetting(const TCHAR* section, const TCHAR* key, Type& var)
|
|||
* ...
|
||||
*
|
||||
* */
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
bool SaveSetting(const char* dev_type, int port, const std::string& key, const TCHAR* name, const Type var)
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -168,7 +169,7 @@ bool SaveSetting(const char* dev_type, int port, const std::string& key, const T
|
|||
return ret;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
bool SaveSetting(const TCHAR* section, const TCHAR* key, const Type var)
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "usb-hid/hidproxy.h"
|
||||
#include "usb-eyetoy/videodeviceproxy.h"
|
||||
|
||||
RegisterDevice *RegisterDevice::registerDevice = nullptr;
|
||||
RegisterDevice* RegisterDevice::registerDevice = nullptr;
|
||||
|
||||
void RegisterAPIs()
|
||||
{
|
||||
|
|
|
@ -46,30 +46,37 @@ 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) {}
|
||||
public:
|
||||
DeviceError(const char* msg)
|
||||
: std::runtime_error(msg)
|
||||
{
|
||||
}
|
||||
virtual ~DeviceError() {}
|
||||
};
|
||||
|
||||
class DeviceProxyBase
|
||||
{
|
||||
public:
|
||||
DeviceProxyBase() {};
|
||||
public:
|
||||
DeviceProxyBase(){};
|
||||
virtual ~DeviceProxyBase() {}
|
||||
virtual USBDevice* CreateDevice(int port) = 0;
|
||||
virtual const TCHAR* Name() const = 0;
|
||||
virtual const char* TypeName() const = 0;
|
||||
virtual int Configure(int port, const std::string& api, void *data) = 0;
|
||||
virtual int Configure(int port, const std::string& api, void* data) = 0;
|
||||
virtual std::list<std::string> ListAPIs() = 0;
|
||||
virtual const TCHAR* LongAPIName(const std::string& name) = 0;
|
||||
virtual int Freeze(int mode, USBDevice *dev, void *data) = 0;
|
||||
virtual int Freeze(int mode, USBDevice* dev, void* data) = 0;
|
||||
|
||||
virtual bool IsValidAPI(const std::string& api)
|
||||
{
|
||||
|
@ -84,7 +91,7 @@ class DeviceProxyBase
|
|||
template <class T>
|
||||
class DeviceProxy : public DeviceProxyBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
DeviceProxy() {}
|
||||
virtual ~DeviceProxy()
|
||||
{
|
||||
|
@ -102,7 +109,7 @@ class DeviceProxy : public DeviceProxyBase
|
|||
{
|
||||
return T::TypeName();
|
||||
}
|
||||
virtual int Configure(int port, const std::string& api, void *data)
|
||||
virtual int Configure(int port, const std::string& api, void* data)
|
||||
{
|
||||
return T::Configure(port, api, data);
|
||||
}
|
||||
|
@ -114,7 +121,7 @@ class DeviceProxy : public DeviceProxyBase
|
|||
{
|
||||
return T::LongAPIName(name);
|
||||
}
|
||||
virtual int Freeze(int mode, USBDevice *dev, void *data)
|
||||
virtual int Freeze(int mode, USBDevice* dev, void* data)
|
||||
{
|
||||
return T::Freeze(mode, dev, data);
|
||||
}
|
||||
|
@ -126,14 +133,19 @@ class RegisterProxy
|
|||
RegisterProxy(const RegisterProxy&) = delete;
|
||||
RegisterProxy() {}
|
||||
|
||||
public:
|
||||
typedef std::map<std::string, std::unique_ptr<T> > RegisterProxyMap;
|
||||
static RegisterProxy& instance() {
|
||||
public:
|
||||
typedef std::map<std::string, std::unique_ptr<T>> RegisterProxyMap;
|
||||
static RegisterProxy& instance()
|
||||
{
|
||||
static RegisterProxy registerProxy;
|
||||
return registerProxy;
|
||||
}
|
||||
|
||||
virtual ~RegisterProxy() { Clear(); OSDebugOut("%p\n", this); }
|
||||
virtual ~RegisterProxy()
|
||||
{
|
||||
Clear();
|
||||
OSDebugOut("%p\n", this);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
|
@ -182,11 +194,12 @@ class RegisterDevice
|
|||
{
|
||||
RegisterDevice(const RegisterDevice&) = delete;
|
||||
RegisterDevice() {}
|
||||
static RegisterDevice *registerDevice;
|
||||
static RegisterDevice* registerDevice;
|
||||
|
||||
public:
|
||||
typedef std::map<DeviceType, std::unique_ptr<DeviceProxyBase> > RegisterDeviceMap;
|
||||
static RegisterDevice& instance() {
|
||||
public:
|
||||
typedef std::map<DeviceType, std::unique_ptr<DeviceProxyBase>> RegisterDeviceMap;
|
||||
static RegisterDevice& instance()
|
||||
{
|
||||
if (!registerDevice)
|
||||
registerDevice = new RegisterDevice();
|
||||
return *registerDevice;
|
||||
|
@ -210,11 +223,10 @@ class RegisterDevice
|
|||
return k.second;
|
||||
return nullptr;*/
|
||||
auto proxy = std::find_if(registerDeviceMap.begin(),
|
||||
registerDeviceMap.end(),
|
||||
[&name](const RegisterDeviceMap::value_type& val) -> bool
|
||||
{
|
||||
return val.second->TypeName() == name;
|
||||
});
|
||||
registerDeviceMap.end(),
|
||||
[&name](const RegisterDeviceMap::value_type& val) -> bool {
|
||||
return val.second->TypeName() == name;
|
||||
});
|
||||
if (proxy != registerDeviceMap.end())
|
||||
return proxy->second.get();
|
||||
return nullptr;
|
||||
|
@ -232,11 +244,10 @@ class RegisterDevice
|
|||
DeviceType Index(const std::string& name)
|
||||
{
|
||||
auto proxy = std::find_if(registerDeviceMap.begin(),
|
||||
registerDeviceMap.end(),
|
||||
[&name](RegisterDeviceMap::value_type& val) -> bool
|
||||
{
|
||||
return val.second->TypeName() == name;
|
||||
});
|
||||
registerDeviceMap.end(),
|
||||
[&name](RegisterDeviceMap::value_type& val) -> bool {
|
||||
return val.second->TypeName() == name;
|
||||
});
|
||||
if (proxy != registerDeviceMap.end())
|
||||
return proxy->first;
|
||||
return DEVTYPE_NONE;
|
||||
|
@ -266,7 +277,7 @@ class RegisterDevice
|
|||
return registerDeviceMap;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
RegisterDeviceMap registerDeviceMap;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,4 +15,3 @@
|
|||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -14,69 +14,581 @@
|
|||
*/
|
||||
|
||||
#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,
|
||||
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,
|
||||
};
|
||||
|
|
|
@ -25,18 +25,18 @@
|
|||
// #define VERBOSE_FUNCTION_ACTUALFILE
|
||||
// #define VERBOSE_WARNING_ACTUALFILE
|
||||
|
||||
extern int IsActualFile(const char *filename);
|
||||
extern void ActualFileDelete(const char *filename);
|
||||
extern void ActualFileRename(const char *origname, const char *newname);
|
||||
extern int IsActualFile(const char* filename);
|
||||
extern void ActualFileDelete(const char* filename);
|
||||
extern void ActualFileRename(const char* origname, const char* newname);
|
||||
|
||||
extern ACTUALHANDLE ActualFileOpenForRead(const char *filename);
|
||||
extern ACTUALHANDLE ActualFileOpenForRead(const char* filename);
|
||||
extern off64_t ActualFileSize(ACTUALHANDLE handle);
|
||||
extern int ActualFileSeek(ACTUALHANDLE handle, off64_t position);
|
||||
extern int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer);
|
||||
extern int ActualFileRead(ACTUALHANDLE handle, int bytes, char* buffer);
|
||||
extern void ActualFileClose(ACTUALHANDLE handle);
|
||||
|
||||
extern ACTUALHANDLE ActualFileOpenForWrite(const char *filename);
|
||||
extern int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer);
|
||||
extern ACTUALHANDLE ActualFileOpenForWrite(const char* filename);
|
||||
extern int ActualFileWrite(ACTUALHANDLE handle, int bytes, char* buffer);
|
||||
|
||||
|
||||
#endif /* ACTUALFILE_H */
|
||||
|
|
|
@ -45,14 +45,14 @@ struct SettingsCB
|
|||
|
||||
gboolean run_msg_dialog(gpointer data)
|
||||
{
|
||||
GtkWidget *dialog = (GtkWidget *)data;
|
||||
gtk_widget_show_all (dialog);
|
||||
gtk_dialog_run (GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
GtkWidget* dialog = (GtkWidget*)data;
|
||||
gtk_widget_show_all(dialog);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void wheeltypeChanged (GtkComboBox *widget, gpointer data)
|
||||
static void wheeltypeChanged(GtkComboBox* widget, gpointer data)
|
||||
{
|
||||
gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
//if(data)
|
||||
|
@ -64,13 +64,13 @@ static void wheeltypeChanged (GtkComboBox *widget, gpointer data)
|
|||
}
|
||||
}
|
||||
|
||||
static void populateApiWidget(SettingsCB *settingsCB, const std::string& device)
|
||||
static void populateApiWidget(SettingsCB* settingsCB, const std::string& device)
|
||||
{
|
||||
gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (settingsCB->combo)));
|
||||
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(settingsCB->combo)));
|
||||
|
||||
auto dev = RegisterDevice::instance().Device( device );
|
||||
auto dev = RegisterDevice::instance().Device(device);
|
||||
int port = 1 - settingsCB->player;
|
||||
GtkComboBox *widget = settingsCB->combo;
|
||||
GtkComboBox* widget = settingsCB->combo;
|
||||
if (dev)
|
||||
{
|
||||
std::string api;
|
||||
|
@ -88,22 +88,22 @@ static void populateApiWidget(SettingsCB *settingsCB, const std::string& device)
|
|||
OSDebugOut("Current api: %s\n", api.c_str());
|
||||
settingsCB->api = api;
|
||||
int i = 0;
|
||||
for(auto& it : dev->ListAPIs())
|
||||
for (auto& it : dev->ListAPIs())
|
||||
{
|
||||
auto name = dev->LongAPIName(it);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), name);
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), name);
|
||||
if (api.size() && api == it)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), i);
|
||||
else
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void deviceChanged (GtkComboBox *widget, gpointer data)
|
||||
static void deviceChanged(GtkComboBox* widget, gpointer data)
|
||||
{
|
||||
SettingsCB *settingsCB = (SettingsCB *)data;
|
||||
SettingsCB* settingsCB = (SettingsCB*)data;
|
||||
gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
int player = settingsCB->player;
|
||||
std::string s;
|
||||
|
@ -114,7 +114,7 @@ static void deviceChanged (GtkComboBox *widget, gpointer data)
|
|||
settingsCB->device = s;
|
||||
populateApiWidget(settingsCB, s);
|
||||
|
||||
if(player == 0)
|
||||
if (player == 0)
|
||||
conf.Port[1] = s;
|
||||
else
|
||||
conf.Port[0] = s;
|
||||
|
@ -122,15 +122,15 @@ static void deviceChanged (GtkComboBox *widget, gpointer data)
|
|||
OSDebugOut("Selected player %d idx: %d [%s]\n", player, active, s.c_str());
|
||||
}
|
||||
|
||||
static void apiChanged (GtkComboBox *widget, gpointer data)
|
||||
static void apiChanged(GtkComboBox* widget, gpointer data)
|
||||
{
|
||||
SettingsCB *settingsCB = (SettingsCB *)data;
|
||||
SettingsCB* settingsCB = (SettingsCB*)data;
|
||||
int player = settingsCB->player;
|
||||
gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
int port = 1 - player;
|
||||
|
||||
auto& name = settingsCB->device;
|
||||
auto dev = RegisterDevice::instance().Device( name );
|
||||
auto dev = RegisterDevice::instance().Device(name);
|
||||
if (dev)
|
||||
{
|
||||
auto apis = dev->ListAPIs();
|
||||
|
@ -152,130 +152,131 @@ static void apiChanged (GtkComboBox *widget, gpointer data)
|
|||
}
|
||||
}
|
||||
|
||||
static void configureApi (GtkWidget *widget, gpointer data)
|
||||
static void configureApi(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
SettingsCB *settingsCB = (SettingsCB *)data;
|
||||
SettingsCB* settingsCB = (SettingsCB*)data;
|
||||
int player = settingsCB->player;
|
||||
int port = 1 - player;
|
||||
|
||||
auto& name = settingsCB->device;
|
||||
auto& api = settingsCB->api;
|
||||
auto dev = RegisterDevice::instance().Device( name );
|
||||
auto dev = RegisterDevice::instance().Device(name);
|
||||
|
||||
OSDebugOut("configure api %s [%s] for player %d\n", api.c_str(), name.c_str(), player);
|
||||
if (dev)
|
||||
{
|
||||
GtkWidget *dlg = GTK_WIDGET (g_object_get_data (G_OBJECT(widget), "dlg"));
|
||||
GtkWidget* dlg = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "dlg"));
|
||||
int res = dev->Configure(port, api, dlg);
|
||||
OSDebugOut("Configure returned %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *new_combobox(const char* label, GtkWidget *vbox)
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox)
|
||||
{
|
||||
GtkWidget *ro_label, *rs_hbox, *rs_label, *rs_cb;
|
||||
|
||||
rs_hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), rs_hbox, FALSE, TRUE, 0);
|
||||
rs_hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), rs_hbox, FALSE, TRUE, 0);
|
||||
|
||||
rs_label = gtk_label_new (label);
|
||||
gtk_box_pack_start (GTK_BOX (rs_hbox), rs_label, FALSE, TRUE, 5);
|
||||
gtk_label_set_justify (GTK_LABEL (rs_label), GTK_JUSTIFY_RIGHT);
|
||||
gtk_misc_set_alignment (GTK_MISC (rs_label), 1, 0.5);
|
||||
rs_label = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_label, FALSE, TRUE, 5);
|
||||
gtk_label_set_justify(GTK_LABEL(rs_label), GTK_JUSTIFY_RIGHT);
|
||||
gtk_misc_set_alignment(GTK_MISC(rs_label), 1, 0.5);
|
||||
|
||||
rs_cb = gtk_combo_box_text_new ();
|
||||
gtk_box_pack_start (GTK_BOX (rs_hbox), rs_cb, TRUE, TRUE, 5);
|
||||
rs_cb = gtk_combo_box_text_new();
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_cb, TRUE, TRUE, 5);
|
||||
return rs_cb;
|
||||
}
|
||||
|
||||
static GtkWidget* new_frame(const char *label, GtkWidget *box)
|
||||
static GtkWidget* new_frame(const char* label, GtkWidget* box)
|
||||
{
|
||||
GtkWidget *ro_frame = gtk_frame_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX (box), ro_frame, TRUE, FALSE, 0);
|
||||
GtkWidget* ro_frame = gtk_frame_new(NULL);
|
||||
gtk_box_pack_start(GTK_BOX(box), ro_frame, TRUE, FALSE, 0);
|
||||
|
||||
GtkWidget *ro_label = gtk_label_new (label);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (ro_frame), ro_label);
|
||||
gtk_label_set_use_markup (GTK_LABEL (ro_label), TRUE);
|
||||
GtkWidget* ro_label = gtk_label_new(label);
|
||||
gtk_frame_set_label_widget(GTK_FRAME(ro_frame), ro_label);
|
||||
gtk_label_set_use_markup(GTK_LABEL(ro_label), TRUE);
|
||||
|
||||
GtkWidget *vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER (ro_frame), vbox);
|
||||
GtkWidget* vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(ro_frame), vbox);
|
||||
return vbox;
|
||||
}
|
||||
|
||||
|
||||
void USBconfigure() {
|
||||
ScopedCoreThreadPause paused_core;
|
||||
void USBconfigure()
|
||||
{
|
||||
ScopedCoreThreadPause paused_core;
|
||||
|
||||
RegisterDevice::Register();
|
||||
LoadConfig();
|
||||
void * that = NULL;
|
||||
void* that = NULL;
|
||||
SettingsCB settingsCB[2];
|
||||
settingsCB[0].player = 0;
|
||||
settingsCB[1].player = 1;
|
||||
|
||||
const char* wt[] = {"Driving Force", "Driving Force Pro", "Driving Force Pro (rev11.02)", "GT Force"};
|
||||
const char *players[] = {"Player 1:", "Player 2:"};
|
||||
const char* players[] = {"Player 1:", "Player 2:"};
|
||||
|
||||
GtkWidget *rs_cb, *vbox;
|
||||
uint32_t idx = 0, sel_idx = 0;
|
||||
|
||||
// Create the dialog window
|
||||
GtkWidget *dlg = gtk_dialog_new_with_buttons (
|
||||
GtkWidget* dlg = gtk_dialog_new_with_buttons(
|
||||
"Qemu USB Settings", NULL, GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
|
||||
GtkWidget *dlg_area_box = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
|
||||
GtkWidget *main_vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER (dlg_area_box), main_vbox);
|
||||
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
|
||||
GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
|
||||
GtkWidget* main_vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg_area_box), main_vbox);
|
||||
|
||||
/*** Device type ***/
|
||||
vbox = new_frame("Select device type:", main_vbox);
|
||||
|
||||
std::string devs[2] = { conf.Port[1], conf.Port[0] };
|
||||
std::string devs[2] = {conf.Port[1], conf.Port[0]};
|
||||
/*** Devices' Comboboxes ***/
|
||||
for(int ply = 0; ply < 2; ply++)
|
||||
for (int ply = 0; ply < 2; ply++)
|
||||
{
|
||||
settingsCB[ply].device = devs[ply];
|
||||
|
||||
rs_cb = new_combobox(players[ply], vbox);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rs_cb), "None");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), 0);
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), "None");
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), 0);
|
||||
|
||||
auto devices = RegisterDevice::instance().Names();
|
||||
int idx = 0, selected = 0;
|
||||
for(auto& device : devices)
|
||||
for (auto& device : devices)
|
||||
{
|
||||
auto deviceProxy = RegisterDevice::instance().Device(device);
|
||||
auto name = deviceProxy->Name();
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rs_cb), name );
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), name);
|
||||
idx++;
|
||||
if (devs[ply] == device)
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), idx);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), idx);
|
||||
}
|
||||
g_signal_connect (G_OBJECT (rs_cb), "changed", G_CALLBACK (deviceChanged), (gpointer)&settingsCB[ply]);
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(deviceChanged), (gpointer)&settingsCB[ply]);
|
||||
}
|
||||
|
||||
/*** APIs ***/
|
||||
vbox = new_frame("Select device API:", main_vbox);
|
||||
|
||||
/*** API Comboboxes ***/
|
||||
for(int ply = 0; ply < 2; ply++)
|
||||
for (int ply = 0; ply < 2; ply++)
|
||||
{
|
||||
rs_cb = new_combobox (players[ply], vbox);
|
||||
settingsCB[ply].combo = GTK_COMBO_BOX (rs_cb);
|
||||
rs_cb = new_combobox(players[ply], vbox);
|
||||
settingsCB[ply].combo = GTK_COMBO_BOX(rs_cb);
|
||||
//gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), sel_idx);
|
||||
g_signal_connect (G_OBJECT (rs_cb), "changed", G_CALLBACK (apiChanged), (gpointer)&settingsCB[ply]);
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(apiChanged), (gpointer)&settingsCB[ply]);
|
||||
|
||||
GtkWidget *hbox = gtk_widget_get_parent (rs_cb);
|
||||
GtkWidget *button = gtk_button_new_with_label ("Configure");
|
||||
gtk_button_set_image(GTK_BUTTON (button), gtk_image_new_from_icon_name ("gtk-preferences", GTK_ICON_SIZE_BUTTON));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 5);
|
||||
GtkWidget* hbox = gtk_widget_get_parent(rs_cb);
|
||||
GtkWidget* button = gtk_button_new_with_label("Configure");
|
||||
gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_icon_name("gtk-preferences", GTK_ICON_SIZE_BUTTON));
|
||||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
|
||||
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (configureApi), (gpointer)&settingsCB[ply]);
|
||||
g_object_set_data (G_OBJECT (button), "dlg", dlg);
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(configureApi), (gpointer)&settingsCB[ply]);
|
||||
g_object_set_data(G_OBJECT(button), "dlg", dlg);
|
||||
|
||||
populateApiWidget(&settingsCB[ply], devs[ply]);
|
||||
}
|
||||
|
@ -283,41 +284,42 @@ void USBconfigure() {
|
|||
/** Wheel type **/
|
||||
vbox = new_frame("Emulated wheel model:", main_vbox);
|
||||
|
||||
for(int ply = 0; ply < 2; ply++)
|
||||
for (int ply = 0; ply < 2; ply++)
|
||||
{
|
||||
int port = 1 - ply;
|
||||
rs_cb = new_combobox (players[ply], vbox);
|
||||
rs_cb = new_combobox(players[ply], vbox);
|
||||
|
||||
sel_idx = 0;
|
||||
|
||||
for (int i = 0; i < countof(wt); i++)
|
||||
{
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rs_cb), wt[i]);
|
||||
if(conf.WheelType[port] == i)
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), wt[i]);
|
||||
if (conf.WheelType[port] == i)
|
||||
sel_idx = i;
|
||||
}
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), sel_idx);
|
||||
g_signal_connect (G_OBJECT (rs_cb), "changed", G_CALLBACK (wheeltypeChanged), reinterpret_cast<gpointer> (port));
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), sel_idx);
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(wheeltypeChanged), reinterpret_cast<gpointer>(port));
|
||||
}
|
||||
|
||||
gtk_widget_show_all (dlg);
|
||||
gtk_widget_show_all(dlg);
|
||||
|
||||
// Modal loop
|
||||
gint result = gtk_dialog_run (GTK_DIALOG (dlg));
|
||||
gtk_widget_destroy (dlg);
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
gtk_widget_destroy(dlg);
|
||||
|
||||
// Wait for all gtk events to be consumed ...
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration_do (FALSE);
|
||||
while (gtk_events_pending())
|
||||
gtk_main_iteration_do(FALSE);
|
||||
|
||||
if (result == GTK_RESPONSE_OK)
|
||||
{
|
||||
SaveConfig();
|
||||
configChanged = true;
|
||||
}
|
||||
// ClearAPIs();
|
||||
// ClearAPIs();
|
||||
paused_core.AllowResume();
|
||||
}
|
||||
|
||||
void CALLBACK USBabout() {
|
||||
void CALLBACK USBabout()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
void SysMessage_stderr(const char *fmt, ...)
|
||||
void SysMessage_stderr(const char* fmt, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
|
|
|
@ -46,14 +46,14 @@
|
|||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int INISaveString(const char *file, const char *section, const char *keyword, const char *value);
|
||||
extern int INILoadString(const char *file, const char *section, const char *keyword, char *buffer);
|
||||
extern int INISaveString(const char* file, const char* section, const char* keyword, const char* value);
|
||||
extern int INILoadString(const char* file, const char* section, const char* keyword, char* buffer);
|
||||
|
||||
extern int INISaveUInt(const char *file, const char *section, const char *keyword, unsigned int value);
|
||||
extern int INILoadUInt(const char *file, const char *section, const char *keyword, unsigned int *buffer);
|
||||
extern int INISaveUInt(const char* file, const char* section, const char* keyword, unsigned int value);
|
||||
extern int INILoadUInt(const char* file, const char* section, const char* keyword, unsigned int* buffer);
|
||||
|
||||
// NULL in the keyword below removes the whole section.
|
||||
extern int INIRemove(const char *file, const char *section, const char *keyword);
|
||||
extern int INIRemove(const char* file, const char* section, const char* keyword);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -23,9 +24,9 @@ std::wostream& operator<<(std::wostream& os, const std::string& s) {
|
|||
|
||||
#ifdef _WIN32
|
||||
static int rateLimit = 0;
|
||||
void _OSDebugOut(const TCHAR *psz_fmt, ...)
|
||||
void _OSDebugOut(const TCHAR* psz_fmt, ...)
|
||||
{
|
||||
if(rateLimit > 0 && rateLimit < 100)
|
||||
if (rateLimit > 0 && rateLimit < 100)
|
||||
{
|
||||
rateLimit++;
|
||||
return;
|
||||
|
|
|
@ -25,29 +25,65 @@ void __Log(const char* fmt, ...);
|
|||
#ifdef _WIN32
|
||||
|
||||
#include <vector>
|
||||
void _OSDebugOut(const TCHAR *psz_fmt, ...);
|
||||
void _OSDebugOut(const TCHAR* psz_fmt, ...);
|
||||
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
|
||||
|
|
|
@ -26,16 +26,16 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define CALLBACK __stdcall
|
||||
#define CALLBACK __stdcall
|
||||
#else
|
||||
# define CALLBACK __attribute__((stdcall))
|
||||
#define CALLBACK __attribute__((stdcall))
|
||||
#endif
|
||||
|
||||
#ifndef EXPORT_C_
|
||||
#ifdef _MSC_VER
|
||||
#define EXPORT_C_(type) extern "C" type CALLBACK
|
||||
#else
|
||||
#define EXPORT_C_(type) extern "C" __attribute__((stdcall,externally_visible,visibility("default"))) type
|
||||
#define EXPORT_C_(type) extern "C" __attribute__((stdcall, externally_visible, visibility("default"))) type
|
||||
//#define EXPORT_C_(type) extern "C" __attribute__((stdcall,visibility("default"))) type
|
||||
#endif
|
||||
#endif
|
||||
|
@ -61,7 +61,7 @@ typedef SSIZE_T ssize_t;
|
|||
|
||||
#define __builtin_constant_p(p) false
|
||||
|
||||
void SysMessageW(const wchar_t *fmt, ...);
|
||||
void SysMessageW(const wchar_t* fmt, ...);
|
||||
#define SysMessage SysMessageW
|
||||
|
||||
#ifndef _T
|
||||
|
@ -85,7 +85,7 @@ void SysMessageW(const wchar_t *fmt, ...);
|
|||
#define TSTDSTRINGSTREAM std::stringstream
|
||||
#define TSTDTOSTRING std::to_string
|
||||
|
||||
void SysMessage(const char *fmt, ...);
|
||||
void SysMessage(const char* fmt, ...);
|
||||
|
||||
#endif //_WIN32
|
||||
|
||||
|
@ -96,22 +96,20 @@ void SysMessage(const char *fmt, ...);
|
|||
|
||||
template <size_t size>
|
||||
errno_t mbstowcs_s(
|
||||
size_t *pReturnValue,
|
||||
size_t* pReturnValue,
|
||||
wchar_t (&wcstr)[size],
|
||||
const char *mbstr,
|
||||
size_t count
|
||||
)
|
||||
const char* mbstr,
|
||||
size_t count)
|
||||
{
|
||||
return mbstowcs_s(pReturnValue, wcstr, size, mbstr, count);
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
errno_t wcstombs_s(
|
||||
size_t *pReturnValue,
|
||||
size_t* pReturnValue,
|
||||
char (&mbstr)[size],
|
||||
const wchar_t *wcstr,
|
||||
size_t count
|
||||
)
|
||||
const wchar_t* wcstr,
|
||||
size_t count)
|
||||
{
|
||||
return wcstombs_s(pReturnValue, mbstr, size, wcstr, count);
|
||||
}
|
||||
|
@ -127,20 +125,20 @@ errno_t wcstombs_s(
|
|||
template <class T, std::size_t N>
|
||||
constexpr std::size_t countof(const T (&)[N]) noexcept
|
||||
{
|
||||
return N;
|
||||
return N;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr std::size_t countof(const T N)
|
||||
{
|
||||
return N.size();
|
||||
return N.size();
|
||||
}
|
||||
|
||||
//TODO Idk, used only in desc.h and struct USBDescriptor should be already packed anyway
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#define PACK(def,name) __pragma( pack(push, 1) ) def name __pragma( pack(pop) )
|
||||
#define PACK(def, name) __pragma(pack(push, 1)) def name __pragma(pack(pop))
|
||||
#elif defined(__clang__)
|
||||
#define PACK(def,name) def __attribute__((packed)) name
|
||||
#define PACK(def, name) def __attribute__((packed)) name
|
||||
#else
|
||||
#define PACK(def,name) def __attribute__((gcc_struct, packed)) name
|
||||
#define PACK(def, name) def __attribute__((gcc_struct, packed)) name
|
||||
#endif
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
//TODO Maybe too much inheritance?
|
||||
class ProxyBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ProxyBase() {}
|
||||
virtual ~ProxyBase() {}
|
||||
virtual const TCHAR* Name() const = 0;
|
||||
virtual int Configure(int port, const char* dev_type, void *data) = 0;
|
||||
virtual int Configure(int port, const char* dev_type, void* data) = 0;
|
||||
};
|
||||
|
|
|
@ -25,76 +25,79 @@
|
|||
|
||||
/* Number of Downstream Ports on the root hub. */
|
||||
|
||||
#define OHCI_MAX_PORTS 15 // status regs from 0x0c54 but usb snooping
|
||||
// reg is at 0x0c80, so only 11 ports?
|
||||
#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 {
|
||||
USBPort port;
|
||||
uint32_t ctrl;
|
||||
typedef struct OHCIPort
|
||||
{
|
||||
USBPort port;
|
||||
uint32_t ctrl;
|
||||
} OHCIPort;
|
||||
|
||||
typedef uint32_t target_phys_addr_t;
|
||||
|
||||
typedef struct OHCIState {
|
||||
target_phys_addr_t mem_base;
|
||||
int mem;
|
||||
uint32_t num_ports;
|
||||
typedef struct OHCIState
|
||||
{
|
||||
target_phys_addr_t mem_base;
|
||||
int mem;
|
||||
uint32_t num_ports;
|
||||
|
||||
uint64_t eof_timer;
|
||||
int64_t sof_time;
|
||||
uint64_t eof_timer;
|
||||
int64_t sof_time;
|
||||
|
||||
/* OHCI state */
|
||||
/* Control partition */
|
||||
uint32_t ctl, status;
|
||||
uint32_t intr_status;
|
||||
uint32_t intr;
|
||||
/* OHCI state */
|
||||
/* Control partition */
|
||||
uint32_t ctl, status;
|
||||
uint32_t intr_status;
|
||||
uint32_t intr;
|
||||
|
||||
/* memory pointer partition */
|
||||
uint32_t hcca;
|
||||
uint32_t ctrl_head, ctrl_cur;
|
||||
uint32_t bulk_head, bulk_cur;
|
||||
uint32_t per_cur;
|
||||
uint32_t done;
|
||||
int32_t done_count;
|
||||
/* memory pointer partition */
|
||||
uint32_t hcca;
|
||||
uint32_t ctrl_head, ctrl_cur;
|
||||
uint32_t bulk_head, bulk_cur;
|
||||
uint32_t per_cur;
|
||||
uint32_t done;
|
||||
int32_t done_count;
|
||||
|
||||
/* Frame counter partition */
|
||||
uint32_t fsmps:15;
|
||||
uint32_t fit:1;
|
||||
uint32_t fi:14;
|
||||
uint32_t frt:1;
|
||||
uint16_t frame_number;
|
||||
uint16_t padding;
|
||||
uint32_t pstart;
|
||||
uint32_t lst;
|
||||
/* Frame counter partition */
|
||||
uint32_t fsmps : 15;
|
||||
uint32_t fit : 1;
|
||||
uint32_t fi : 14;
|
||||
uint32_t frt : 1;
|
||||
uint16_t frame_number;
|
||||
uint16_t padding;
|
||||
uint32_t pstart;
|
||||
uint32_t lst;
|
||||
|
||||
/* Root Hub partition */
|
||||
uint32_t rhdesc_a, rhdesc_b;
|
||||
uint32_t rhstatus;
|
||||
OHCIPort rhport[OHCI_MAX_PORTS];
|
||||
|
||||
/* Active packets. */
|
||||
uint32_t old_ctl;
|
||||
USBPacket usb_packet;
|
||||
uint8_t usb_buf[8192];
|
||||
uint32_t async_td;
|
||||
bool async_complete;
|
||||
|
||||
/* Root Hub partition */
|
||||
uint32_t rhdesc_a, rhdesc_b;
|
||||
uint32_t rhstatus;
|
||||
OHCIPort rhport[OHCI_MAX_PORTS];
|
||||
|
||||
/* Active packets. */
|
||||
uint32_t old_ctl;
|
||||
USBPacket usb_packet;
|
||||
uint8_t usb_buf[8192];
|
||||
uint32_t async_td;
|
||||
bool async_complete;
|
||||
|
||||
} OHCIState;
|
||||
|
||||
/* Host Controller Communications Area */
|
||||
struct ohci_hcca {
|
||||
uint32_t intr[32];
|
||||
uint16_t frame, pad;
|
||||
uint32_t done;
|
||||
struct ohci_hcca
|
||||
{
|
||||
uint32_t intr[32];
|
||||
uint16_t frame, pad;
|
||||
uint32_t done;
|
||||
};
|
||||
|
||||
// No offsetof in C++.
|
||||
#ifndef offsetof
|
||||
#define offsetof_(x,z) (intptr_t(&((x)->z)) - intptr_t(x))
|
||||
#define offsetof(x,z) offsetof_((x*)0,z)
|
||||
#define offsetof_(x, z) (intptr_t(&((x)->z)) - intptr_t(x))
|
||||
#define offsetof(x, z) offsetof_((x*)0, z)
|
||||
#endif
|
||||
|
||||
//ISO C++ forbids declaration of ‘typeof’ with no type
|
||||
|
@ -103,200 +106,204 @@ struct ohci_hcca {
|
|||
const typeof(((type *) 0)->member) *__mptr = (ptr); \
|
||||
(type *) ((char *) __mptr - offsetof(type, member));})
|
||||
*/
|
||||
#define CONTAINER_OF(p, type, field) ((type*) ((char*)p - ((ptrdiff_t)&((type*)0)->field)))
|
||||
#define CONTAINER_OF(p, type, field) ((type*)((char*)p - ((ptrdiff_t) & ((type*)0)->field)))
|
||||
|
||||
#define HCCA_WRITEBACK_OFFSET 128 //offsetof(struct ohci_hcca, frame)
|
||||
#define HCCA_WRITEBACK_SIZE 8 /* frame, pad, done */
|
||||
#define HCCA_WRITEBACK_OFFSET 128 //offsetof(struct ohci_hcca, frame)
|
||||
#define HCCA_WRITEBACK_SIZE 8 /* frame, pad, done */
|
||||
|
||||
#define ED_WBACK_OFFSET 8 //offsetof(struct ohci_ed, head)
|
||||
#define ED_WBACK_SIZE 4
|
||||
#define ED_WBACK_SIZE 4
|
||||
|
||||
/* Bitfields for the first word of an Endpoint Descriptor. */
|
||||
#define OHCI_ED_FA_SHIFT 0 //device address
|
||||
#define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT)
|
||||
#define OHCI_ED_EN_SHIFT 7 //endpoint number
|
||||
#define OHCI_ED_EN_MASK (0xf<<OHCI_ED_EN_SHIFT)
|
||||
#define OHCI_ED_D_SHIFT 11 //direction
|
||||
#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT)
|
||||
#define OHCI_ED_S (1<<13) //speed 0 - full, 1 - low
|
||||
#define OHCI_ED_K (1<<14) //skip ED if 1
|
||||
#define OHCI_ED_F (1<<15) //format 0 - inter, bulk or setup, 1 - isoch
|
||||
#define OHCI_ED_FA_SHIFT 0 //device address
|
||||
#define OHCI_ED_FA_MASK (0x7f << OHCI_ED_FA_SHIFT)
|
||||
#define OHCI_ED_EN_SHIFT 7 //endpoint number
|
||||
#define OHCI_ED_EN_MASK (0xf << OHCI_ED_EN_SHIFT)
|
||||
#define OHCI_ED_D_SHIFT 11 //direction
|
||||
#define OHCI_ED_D_MASK (3 << OHCI_ED_D_SHIFT)
|
||||
#define OHCI_ED_S (1 << 13) //speed 0 - full, 1 - low
|
||||
#define OHCI_ED_K (1 << 14) //skip ED if 1
|
||||
#define OHCI_ED_F (1 << 15) //format 0 - inter, bulk or setup, 1 - isoch
|
||||
//#define OHCI_ED_MPS_SHIFT 7
|
||||
//#define OHCI_ED_MPS_MASK (0xf<<OHCI_ED_FA_SHIFT)
|
||||
|
||||
#define OHCI_ED_MPS_SHIFT 16 //max packet size
|
||||
#define OHCI_ED_MPS_MASK (0x7ff<<OHCI_ED_MPS_SHIFT)
|
||||
#define OHCI_ED_MPS_MASK (0x7ff << OHCI_ED_MPS_SHIFT)
|
||||
|
||||
/* Flags in the head field of an Endpoint Descriptor. */
|
||||
#define OHCI_ED_H 1 //halted
|
||||
#define OHCI_ED_C 2
|
||||
#define OHCI_ED_H 1 //halted
|
||||
#define OHCI_ED_C 2
|
||||
|
||||
/* Bitfields for the first word of a Transfer Descriptor. */
|
||||
#define OHCI_TD_R (1<<18)
|
||||
#define OHCI_TD_DP_SHIFT 19
|
||||
#define OHCI_TD_DP_MASK (3<<OHCI_TD_DP_SHIFT)
|
||||
#define OHCI_TD_DI_SHIFT 21
|
||||
#define OHCI_TD_DI_MASK (7<<OHCI_TD_DI_SHIFT)
|
||||
#define OHCI_TD_T0 (1<<24)
|
||||
#define OHCI_TD_T1 (1<<24)
|
||||
#define OHCI_TD_EC_SHIFT 26
|
||||
#define OHCI_TD_EC_MASK (3<<OHCI_TD_EC_SHIFT)
|
||||
#define OHCI_TD_CC_SHIFT 28
|
||||
#define OHCI_TD_CC_MASK (0xf<<OHCI_TD_CC_SHIFT)
|
||||
#define OHCI_TD_R (1 << 18)
|
||||
#define OHCI_TD_DP_SHIFT 19
|
||||
#define OHCI_TD_DP_MASK (3 << OHCI_TD_DP_SHIFT)
|
||||
#define OHCI_TD_DI_SHIFT 21
|
||||
#define OHCI_TD_DI_MASK (7 << OHCI_TD_DI_SHIFT)
|
||||
#define OHCI_TD_T0 (1 << 24)
|
||||
#define OHCI_TD_T1 (1 << 24)
|
||||
#define OHCI_TD_EC_SHIFT 26
|
||||
#define OHCI_TD_EC_MASK (3 << OHCI_TD_EC_SHIFT)
|
||||
#define OHCI_TD_CC_SHIFT 28
|
||||
#define OHCI_TD_CC_MASK (0xf << OHCI_TD_CC_SHIFT)
|
||||
|
||||
/* Bitfields for the first word of an Isochronous Transfer Descriptor. */
|
||||
/* CC & DI - same as in the General Transfer Descriptor */
|
||||
#define OHCI_TD_SF_SHIFT 0
|
||||
#define OHCI_TD_SF_MASK (0xffff<<OHCI_TD_SF_SHIFT)
|
||||
#define OHCI_TD_FC_SHIFT 24
|
||||
#define OHCI_TD_FC_MASK (7<<OHCI_TD_FC_SHIFT)
|
||||
#define OHCI_TD_SF_SHIFT 0
|
||||
#define OHCI_TD_SF_MASK (0xffff << OHCI_TD_SF_SHIFT)
|
||||
#define OHCI_TD_FC_SHIFT 24
|
||||
#define OHCI_TD_FC_MASK (7 << OHCI_TD_FC_SHIFT)
|
||||
|
||||
/* Isochronous Transfer Descriptor - Offset / PacketStatusWord */
|
||||
#define OHCI_TD_PSW_CC_SHIFT 12
|
||||
#define OHCI_TD_PSW_CC_MASK (0xf<<OHCI_TD_PSW_CC_SHIFT)
|
||||
#define OHCI_TD_PSW_CC_MASK (0xf << OHCI_TD_PSW_CC_SHIFT)
|
||||
#define OHCI_TD_PSW_SIZE_SHIFT 0
|
||||
#define OHCI_TD_PSW_SIZE_MASK (0xfff<<OHCI_TD_PSW_SIZE_SHIFT)
|
||||
#define OHCI_TD_PSW_SIZE_MASK (0xfff << OHCI_TD_PSW_SIZE_SHIFT)
|
||||
|
||||
#define OHCI_PAGE_MASK 0xfffff000
|
||||
#define OHCI_OFFSET_MASK 0xfff
|
||||
#define OHCI_PAGE_MASK 0xfffff000
|
||||
#define OHCI_OFFSET_MASK 0xfff
|
||||
|
||||
#define OHCI_DPTR_MASK 0xfffffff0
|
||||
#define OHCI_DPTR_MASK 0xfffffff0
|
||||
|
||||
#define OHCI_BM(val, field) \
|
||||
(((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
|
||||
(((val)&OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
|
||||
|
||||
#define OHCI_SET_BM(val, field, newval) do { \
|
||||
val &= ~OHCI_##field##_MASK; \
|
||||
val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
|
||||
} while(0)
|
||||
#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 {
|
||||
uint32_t flags;
|
||||
uint32_t tail;
|
||||
uint32_t head;
|
||||
uint32_t next;
|
||||
struct ohci_ed
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t tail;
|
||||
uint32_t head;
|
||||
uint32_t next;
|
||||
};
|
||||
|
||||
/* General transfer descriptor */
|
||||
struct ohci_td {
|
||||
uint32_t flags;
|
||||
uint32_t cbp;
|
||||
uint32_t next;
|
||||
uint32_t be;
|
||||
struct ohci_td
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t cbp;
|
||||
uint32_t next;
|
||||
uint32_t be;
|
||||
};
|
||||
|
||||
/* Isochronous transfer descriptor */
|
||||
struct ohci_iso_td {
|
||||
uint32_t flags;
|
||||
uint32_t bp;
|
||||
uint32_t next;
|
||||
uint32_t be;
|
||||
uint16_t offset[8];
|
||||
struct ohci_iso_td
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t bp;
|
||||
uint32_t next;
|
||||
uint32_t be;
|
||||
uint16_t offset[8];
|
||||
};
|
||||
|
||||
#define USB_HZ 12000000
|
||||
#define USB_HZ 12000000
|
||||
|
||||
/* OHCI Local stuff */
|
||||
#define OHCI_CTL_CBSR ((1<<0)|(1<<1))
|
||||
#define OHCI_CTL_PLE (1<<2)
|
||||
#define OHCI_CTL_IE (1<<3)
|
||||
#define OHCI_CTL_CLE (1<<4)
|
||||
#define OHCI_CTL_BLE (1<<5)
|
||||
#define OHCI_CTL_HCFS ((1<<6)|(1<<7))
|
||||
#define OHCI_USB_RESET 0x00
|
||||
#define OHCI_USB_RESUME 0x40
|
||||
#define OHCI_USB_OPERATIONAL 0x80
|
||||
#define OHCI_USB_SUSPEND 0xc0
|
||||
#define OHCI_CTL_IR (1<<8)
|
||||
#define OHCI_CTL_RWC (1<<9)
|
||||
#define OHCI_CTL_RWE (1<<10)
|
||||
#define OHCI_CTL_CBSR ((1 << 0) | (1 << 1))
|
||||
#define OHCI_CTL_PLE (1 << 2)
|
||||
#define OHCI_CTL_IE (1 << 3)
|
||||
#define OHCI_CTL_CLE (1 << 4)
|
||||
#define OHCI_CTL_BLE (1 << 5)
|
||||
#define OHCI_CTL_HCFS ((1 << 6) | (1 << 7))
|
||||
#define OHCI_USB_RESET 0x00
|
||||
#define OHCI_USB_RESUME 0x40
|
||||
#define OHCI_USB_OPERATIONAL 0x80
|
||||
#define OHCI_USB_SUSPEND 0xc0
|
||||
#define OHCI_CTL_IR (1 << 8)
|
||||
#define OHCI_CTL_RWC (1 << 9)
|
||||
#define OHCI_CTL_RWE (1 << 10)
|
||||
|
||||
#define OHCI_STATUS_HCR (1<<0)
|
||||
#define OHCI_STATUS_CLF (1<<1)
|
||||
#define OHCI_STATUS_BLF (1<<2)
|
||||
#define OHCI_STATUS_OCR (1<<3)
|
||||
#define OHCI_STATUS_SOC ((1<<6)|(1<<7)) //TODO LSI has SOC at bits 16,17?
|
||||
#define OHCI_STATUS_HCR (1 << 0)
|
||||
#define OHCI_STATUS_CLF (1 << 1)
|
||||
#define OHCI_STATUS_BLF (1 << 2)
|
||||
#define OHCI_STATUS_OCR (1 << 3)
|
||||
#define OHCI_STATUS_SOC ((1 << 6) | (1 << 7)) //TODO LSI has SOC at bits 16,17?
|
||||
|
||||
#define OHCI_INTR_SO (1U<<0) /* Scheduling overrun */
|
||||
#define OHCI_INTR_WD (1U<<1) /* HcDoneHead writeback */
|
||||
#define OHCI_INTR_SF (1U<<2) /* Start of frame */
|
||||
#define OHCI_INTR_RD (1U<<3) /* Resume detect */
|
||||
#define OHCI_INTR_UE (1U<<4) /* Unrecoverable error */
|
||||
#define OHCI_INTR_FNO (1U<<5) /* Frame number overflow */
|
||||
#define OHCI_INTR_RHSC (1U<<6) /* Root hub status change */
|
||||
#define OHCI_INTR_OC (1U<<30) /* Ownership change */
|
||||
#define OHCI_INTR_MIE (1U<<31) /* Master Interrupt Enable */
|
||||
#define OHCI_INTR_SO (1U << 0) /* Scheduling overrun */
|
||||
#define OHCI_INTR_WD (1U << 1) /* HcDoneHead writeback */
|
||||
#define OHCI_INTR_SF (1U << 2) /* Start of frame */
|
||||
#define OHCI_INTR_RD (1U << 3) /* Resume detect */
|
||||
#define OHCI_INTR_UE (1U << 4) /* Unrecoverable error */
|
||||
#define OHCI_INTR_FNO (1U << 5) /* Frame number overflow */
|
||||
#define OHCI_INTR_RHSC (1U << 6) /* Root hub status change */
|
||||
#define OHCI_INTR_OC (1U << 30) /* Ownership change */
|
||||
#define OHCI_INTR_MIE (1U << 31) /* Master Interrupt Enable */
|
||||
|
||||
#define OHCI_HCCA_SIZE 0x100
|
||||
#define OHCI_HCCA_MASK 0xffffff00
|
||||
#define OHCI_HCCA_SIZE 0x100
|
||||
#define OHCI_HCCA_MASK 0xffffff00
|
||||
|
||||
#define OHCI_EDPTR_MASK 0xfffffff0
|
||||
#define OHCI_EDPTR_MASK 0xfffffff0
|
||||
|
||||
#define OHCI_FMI_FI 0x00003fff
|
||||
#define OHCI_FMI_FSMPS 0xffff0000
|
||||
#define OHCI_FMI_FIT 0x80000000
|
||||
#define OHCI_FMI_FI 0x00003fff
|
||||
#define OHCI_FMI_FSMPS 0xffff0000
|
||||
#define OHCI_FMI_FIT 0x80000000
|
||||
|
||||
#define OHCI_FR_RT (1U<<31)
|
||||
#define OHCI_FR_RT (1U << 31)
|
||||
|
||||
#define OHCI_LS_THRESH 0x628
|
||||
#define OHCI_LS_THRESH 0x628
|
||||
|
||||
#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */
|
||||
#define OHCI_RHA_PSM (1<<8)
|
||||
#define OHCI_RHA_NPS (1<<9)
|
||||
#define OHCI_RHA_DT (1<<10)
|
||||
#define OHCI_RHA_OCPM (1<<11)
|
||||
#define OHCI_RHA_NOCP (1<<12)
|
||||
#define OHCI_RHA_POTPGT_MASK 0xff000000
|
||||
#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */
|
||||
#define OHCI_RHA_PSM (1 << 8)
|
||||
#define OHCI_RHA_NPS (1 << 9)
|
||||
#define OHCI_RHA_DT (1 << 10)
|
||||
#define OHCI_RHA_OCPM (1 << 11)
|
||||
#define OHCI_RHA_NOCP (1 << 12)
|
||||
#define OHCI_RHA_POTPGT_MASK 0xff000000
|
||||
|
||||
#define OHCI_RHS_LPS (1U<<0)
|
||||
#define OHCI_RHS_OCI (1U<<1)
|
||||
#define OHCI_RHS_DRWE (1U<<15)
|
||||
#define OHCI_RHS_LPSC (1U<<16)
|
||||
#define OHCI_RHS_OCIC (1U<<17)
|
||||
#define OHCI_RHS_CRWE (1U<<31)
|
||||
#define OHCI_RHS_LPS (1U << 0)
|
||||
#define OHCI_RHS_OCI (1U << 1)
|
||||
#define OHCI_RHS_DRWE (1U << 15)
|
||||
#define OHCI_RHS_LPSC (1U << 16)
|
||||
#define OHCI_RHS_OCIC (1U << 17)
|
||||
#define OHCI_RHS_CRWE (1U << 31)
|
||||
|
||||
#define OHCI_PORT_CCS (1<<0)
|
||||
#define OHCI_PORT_PES (1<<1)
|
||||
#define OHCI_PORT_PSS (1<<2)
|
||||
#define OHCI_PORT_POCI (1<<3)
|
||||
#define OHCI_PORT_PRS (1<<4)
|
||||
#define OHCI_PORT_PPS (1<<8)
|
||||
#define OHCI_PORT_LSDA (1<<9)
|
||||
#define OHCI_PORT_CSC (1<<16)
|
||||
#define OHCI_PORT_PESC (1<<17)
|
||||
#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_CCS (1 << 0)
|
||||
#define OHCI_PORT_PES (1 << 1)
|
||||
#define OHCI_PORT_PSS (1 << 2)
|
||||
#define OHCI_PORT_POCI (1 << 3)
|
||||
#define OHCI_PORT_PRS (1 << 4)
|
||||
#define OHCI_PORT_PPS (1 << 8)
|
||||
#define OHCI_PORT_LSDA (1 << 9)
|
||||
#define OHCI_PORT_CSC (1 << 16)
|
||||
#define OHCI_PORT_PESC (1 << 17)
|
||||
#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_TD_DIR_SETUP 0x0
|
||||
#define OHCI_TD_DIR_OUT 0x1
|
||||
#define OHCI_TD_DIR_IN 0x2
|
||||
#define OHCI_TD_DIR_RESERVED 0x3
|
||||
#define OHCI_TD_DIR_SETUP 0x0
|
||||
#define OHCI_TD_DIR_OUT 0x1
|
||||
#define OHCI_TD_DIR_IN 0x2
|
||||
#define OHCI_TD_DIR_RESERVED 0x3
|
||||
|
||||
#define OHCI_CC_NOERROR 0x0
|
||||
#define OHCI_CC_CRC 0x1
|
||||
#define OHCI_CC_BITSTUFFING 0x2
|
||||
#define OHCI_CC_DATATOGGLEMISMATCH 0x3
|
||||
#define OHCI_CC_STALL 0x4
|
||||
#define OHCI_CC_NOERROR 0x0
|
||||
#define OHCI_CC_CRC 0x1
|
||||
#define OHCI_CC_BITSTUFFING 0x2
|
||||
#define OHCI_CC_DATATOGGLEMISMATCH 0x3
|
||||
#define OHCI_CC_STALL 0x4
|
||||
#define OHCI_CC_DEVICENOTRESPONDING 0x5
|
||||
#define OHCI_CC_PIDCHECKFAILURE 0x6
|
||||
#define OHCI_CC_UNDEXPETEDPID 0x7 // the what?
|
||||
#define OHCI_CC_DATAOVERRUN 0x8
|
||||
#define OHCI_CC_DATAUNDERRUN 0x9
|
||||
#define OHCI_CC_BUFFEROVERRUN 0xc
|
||||
#define OHCI_CC_BUFFERUNDERRUN 0xd
|
||||
#define OHCI_CC_PIDCHECKFAILURE 0x6
|
||||
#define OHCI_CC_UNDEXPETEDPID 0x7 // the what?
|
||||
#define OHCI_CC_DATAOVERRUN 0x8
|
||||
#define OHCI_CC_DATAUNDERRUN 0x9
|
||||
#define OHCI_CC_BUFFEROVERRUN 0xc
|
||||
#define OHCI_CC_BUFFERUNDERRUN 0xd
|
||||
|
||||
OHCIState *ohci_create(uint32_t base, int ports);
|
||||
OHCIState* ohci_create(uint32_t base, int ports);
|
||||
|
||||
uint32_t ohci_mem_read(OHCIState *ohci, uint32_t addr );
|
||||
void ohci_mem_write(OHCIState *ohci, uint32_t addr, uint32_t value );
|
||||
void ohci_frame_boundary(void *opaque);
|
||||
uint32_t ohci_mem_read(OHCIState* ohci, uint32_t addr);
|
||||
void ohci_mem_write(OHCIState* ohci, uint32_t addr, uint32_t value);
|
||||
void ohci_frame_boundary(void* opaque);
|
||||
|
||||
void ohci_hard_reset(OHCIState *ohci);
|
||||
void ohci_soft_reset(OHCIState *ohci);
|
||||
int ohci_bus_start(OHCIState *ohci);
|
||||
void ohci_bus_stop(OHCIState *ohci);
|
||||
void ohci_hard_reset(OHCIState* ohci);
|
||||
void ohci_soft_reset(OHCIState* ohci);
|
||||
int ohci_bus_start(OHCIState* ohci);
|
||||
void ohci_bus_stop(OHCIState* ohci);
|
||||
#endif
|
||||
|
|
|
@ -18,72 +18,80 @@
|
|||
|
||||
#define USB_DEVICE_GET_CLASS(p) (&p->klass)
|
||||
|
||||
static void usb_device_realize(USBDevice *dev/*, Error **errp*/)
|
||||
static void usb_device_realize(USBDevice* dev /*, Error **errp*/)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
|
||||
if (klass->realize) {
|
||||
klass->realize(dev/*, errp*/);
|
||||
}
|
||||
if (klass->realize)
|
||||
{
|
||||
klass->realize(dev /*, errp*/);
|
||||
}
|
||||
}
|
||||
|
||||
USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr)
|
||||
USBDevice* usb_device_find_device(USBDevice* dev, uint8_t addr)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->find_device) {
|
||||
return klass->find_device(dev, addr);
|
||||
}
|
||||
return NULL;
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->find_device)
|
||||
{
|
||||
return klass->find_device(dev, addr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usb_device_unrealize(USBDevice *dev/*, Error **errp*/)
|
||||
static void usb_device_unrealize(USBDevice* dev /*, Error **errp*/)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
|
||||
if (klass->unrealize) {
|
||||
klass->unrealize(dev/*, errp*/);
|
||||
}
|
||||
if (klass->unrealize)
|
||||
{
|
||||
klass->unrealize(dev /*, errp*/);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
|
||||
void usb_device_cancel_packet(USBDevice* dev, USBPacket* p)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->cancel_packet) {
|
||||
klass->cancel_packet(dev, p);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->cancel_packet)
|
||||
{
|
||||
klass->cancel_packet(dev, p);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_handle_attach(USBDevice *dev)
|
||||
void usb_device_handle_attach(USBDevice* dev)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_attach) {
|
||||
klass->handle_attach(dev);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_attach)
|
||||
{
|
||||
klass->handle_attach(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_handle_reset(USBDevice *dev)
|
||||
void usb_device_handle_reset(USBDevice* dev)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_reset) {
|
||||
klass->handle_reset(dev);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_reset)
|
||||
{
|
||||
klass->handle_reset(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
|
||||
int value, int index, int length, uint8_t *data)
|
||||
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) {
|
||||
klass->handle_control(dev, p, request, value, index, length, data);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_control)
|
||||
{
|
||||
klass->handle_control(dev, p, request, value, index, length, data);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_handle_data(USBDevice *dev, USBPacket *p)
|
||||
void usb_device_handle_data(USBDevice* dev, USBPacket* p)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_data) {
|
||||
klass->handle_data(dev, p);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->handle_data)
|
||||
{
|
||||
klass->handle_data(dev, p);
|
||||
}
|
||||
}
|
||||
|
||||
/*const char *usb_device_get_product_desc(USBDevice *dev)
|
||||
|
@ -92,54 +100,60 @@ void usb_device_handle_data(USBDevice *dev, USBPacket *p)
|
|||
return klass->product_desc;
|
||||
}*/
|
||||
|
||||
const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
|
||||
const USBDesc* usb_device_get_usb_desc(USBDevice* dev)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (dev->usb_desc) {
|
||||
return dev->usb_desc;
|
||||
}
|
||||
return klass->usb_desc;
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (dev->usb_desc)
|
||||
{
|
||||
return dev->usb_desc;
|
||||
}
|
||||
return klass->usb_desc;
|
||||
}
|
||||
|
||||
void usb_device_set_interface(USBDevice *dev, int intf,
|
||||
int alt_old, int alt_new)
|
||||
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) {
|
||||
klass->set_interface(dev, intf, alt_old, alt_new);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->set_interface)
|
||||
{
|
||||
klass->set_interface(dev, intf, alt_old, alt_new);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
|
||||
void usb_device_flush_ep_queue(USBDevice* dev, USBEndpoint* ep)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->flush_ep_queue) {
|
||||
klass->flush_ep_queue(dev, ep);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->flush_ep_queue)
|
||||
{
|
||||
klass->flush_ep_queue(dev, ep);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
|
||||
void usb_device_ep_stopped(USBDevice* dev, USBEndpoint* ep)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->ep_stopped) {
|
||||
klass->ep_stopped(dev, ep);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->ep_stopped)
|
||||
{
|
||||
klass->ep_stopped(dev, ep);
|
||||
}
|
||||
}
|
||||
|
||||
int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
|
||||
int streams)
|
||||
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) {
|
||||
return klass->alloc_streams(dev, eps, nr_eps, streams);
|
||||
}
|
||||
return 0;
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->alloc_streams)
|
||||
{
|
||||
return klass->alloc_streams(dev, eps, nr_eps, streams);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usb_device_free_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) {
|
||||
klass->free_streams(dev, eps, nr_eps);
|
||||
}
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
|
||||
if (klass->free_streams)
|
||||
{
|
||||
klass->free_streams(dev, eps, nr_eps);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,199 +20,222 @@
|
|||
#include "../platcompat.h"
|
||||
|
||||
/* binary representation */
|
||||
PACK(typedef struct USBDescriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
union {
|
||||
struct {
|
||||
uint8_t bcdUSB_lo;
|
||||
uint8_t bcdUSB_hi;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t idVendor_lo;
|
||||
uint8_t idVendor_hi;
|
||||
uint8_t idProduct_lo;
|
||||
uint8_t idProduct_hi;
|
||||
uint8_t bcdDevice_lo;
|
||||
uint8_t bcdDevice_hi;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} device;
|
||||
struct {
|
||||
uint8_t bcdUSB_lo;
|
||||
uint8_t bcdUSB_hi;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
uint8_t bReserved;
|
||||
} device_qualifier;
|
||||
struct {
|
||||
uint8_t wTotalLength_lo;
|
||||
uint8_t wTotalLength_hi;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} config;
|
||||
struct {
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} intf;
|
||||
struct {
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wMaxPacketSize_lo;
|
||||
uint8_t wMaxPacketSize_hi;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh; /* only audio ep */
|
||||
uint8_t bSynchAddress; /* only audio ep */
|
||||
} endpoint;
|
||||
struct {
|
||||
uint8_t bMaxBurst;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wBytesPerInterval_lo;
|
||||
uint8_t wBytesPerInterval_hi;
|
||||
} super_endpoint;
|
||||
struct {
|
||||
uint8_t wTotalLength_lo;
|
||||
uint8_t wTotalLength_hi;
|
||||
uint8_t bNumDeviceCaps;
|
||||
} bos;
|
||||
struct {
|
||||
uint8_t bDevCapabilityType;
|
||||
union {
|
||||
struct {
|
||||
uint8_t bmAttributes_1;
|
||||
uint8_t bmAttributes_2;
|
||||
uint8_t bmAttributes_3;
|
||||
uint8_t bmAttributes_4;
|
||||
} usb2_ext;
|
||||
struct {
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wSpeedsSupported_lo;
|
||||
uint8_t wSpeedsSupported_hi;
|
||||
uint8_t bFunctionalitySupport;
|
||||
uint8_t bU1DevExitLat;
|
||||
uint8_t wU2DevExitLat_lo;
|
||||
uint8_t wU2DevExitLat_hi;
|
||||
} super;
|
||||
} u;
|
||||
} cap;
|
||||
} u;
|
||||
}, USBDescriptor);
|
||||
PACK(
|
||||
typedef struct USBDescriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bcdUSB_lo;
|
||||
uint8_t bcdUSB_hi;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t idVendor_lo;
|
||||
uint8_t idVendor_hi;
|
||||
uint8_t idProduct_lo;
|
||||
uint8_t idProduct_hi;
|
||||
uint8_t bcdDevice_lo;
|
||||
uint8_t bcdDevice_hi;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} device;
|
||||
struct
|
||||
{
|
||||
uint8_t bcdUSB_lo;
|
||||
uint8_t bcdUSB_hi;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
uint8_t bReserved;
|
||||
} device_qualifier;
|
||||
struct
|
||||
{
|
||||
uint8_t wTotalLength_lo;
|
||||
uint8_t wTotalLength_hi;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} config;
|
||||
struct
|
||||
{
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} intf;
|
||||
struct
|
||||
{
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wMaxPacketSize_lo;
|
||||
uint8_t wMaxPacketSize_hi;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh; /* only audio ep */
|
||||
uint8_t bSynchAddress; /* only audio ep */
|
||||
} endpoint;
|
||||
struct
|
||||
{
|
||||
uint8_t bMaxBurst;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wBytesPerInterval_lo;
|
||||
uint8_t wBytesPerInterval_hi;
|
||||
} super_endpoint;
|
||||
struct
|
||||
{
|
||||
uint8_t wTotalLength_lo;
|
||||
uint8_t wTotalLength_hi;
|
||||
uint8_t bNumDeviceCaps;
|
||||
} bos;
|
||||
struct
|
||||
{
|
||||
uint8_t bDevCapabilityType;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bmAttributes_1;
|
||||
uint8_t bmAttributes_2;
|
||||
uint8_t bmAttributes_3;
|
||||
uint8_t bmAttributes_4;
|
||||
} usb2_ext;
|
||||
struct
|
||||
{
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wSpeedsSupported_lo;
|
||||
uint8_t wSpeedsSupported_hi;
|
||||
uint8_t bFunctionalitySupport;
|
||||
uint8_t bU1DevExitLat;
|
||||
uint8_t wU2DevExitLat_lo;
|
||||
uint8_t wU2DevExitLat_hi;
|
||||
} super;
|
||||
} u;
|
||||
} cap;
|
||||
} u;
|
||||
},
|
||||
USBDescriptor);
|
||||
|
||||
struct USBDescID {
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
struct USBDescID
|
||||
{
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
};
|
||||
|
||||
struct USBDescDevice {
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
struct USBDescDevice
|
||||
{
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
|
||||
std::vector<USBDescConfig> confs;
|
||||
std::vector<USBDescConfig> confs;
|
||||
};
|
||||
|
||||
struct USBDescConfig {
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
struct USBDescConfig
|
||||
{
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
|
||||
/* grouped interfaces */
|
||||
//uint8_t nif_groups;
|
||||
std::vector<USBDescIfaceAssoc> if_groups;
|
||||
std::vector<USBDescIfaceAssoc> if_groups;
|
||||
|
||||
/* "normal" interfaces */
|
||||
//uint8_t nif;
|
||||
std::vector<USBDescIface> ifs;
|
||||
std::vector<USBDescIface> ifs;
|
||||
};
|
||||
|
||||
/* conceptually an Interface Association Descriptor, and releated interfaces */
|
||||
struct USBDescIfaceAssoc {
|
||||
uint8_t bFirstInterface;
|
||||
uint8_t bInterfaceCount;
|
||||
uint8_t bFunctionClass;
|
||||
uint8_t bFunctionSubClass;
|
||||
uint8_t bFunctionProtocol;
|
||||
uint8_t iFunction;
|
||||
struct USBDescIfaceAssoc
|
||||
{
|
||||
uint8_t bFirstInterface;
|
||||
uint8_t bInterfaceCount;
|
||||
uint8_t bFunctionClass;
|
||||
uint8_t bFunctionSubClass;
|
||||
uint8_t bFunctionProtocol;
|
||||
uint8_t iFunction;
|
||||
|
||||
//uint8_t nif;
|
||||
std::vector<USBDescIface> ifs;
|
||||
std::vector<USBDescIface> ifs;
|
||||
};
|
||||
|
||||
struct USBDescIface {
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
struct USBDescIface
|
||||
{
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
|
||||
//uint8_t ndesc;
|
||||
std::vector<USBDescOther> descs;
|
||||
std::vector<USBDescEndpoint> eps;
|
||||
std::vector<USBDescOther> descs;
|
||||
std::vector<USBDescEndpoint> eps;
|
||||
};
|
||||
|
||||
struct USBDescEndpoint {
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh;
|
||||
uint8_t bSynchAddress;
|
||||
struct USBDescEndpoint
|
||||
{
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh;
|
||||
uint8_t bSynchAddress;
|
||||
|
||||
uint8_t is_audio; /* has bRefresh + bSynchAddress */
|
||||
const uint8_t *extra;
|
||||
uint8_t is_audio; /* has bRefresh + bSynchAddress */
|
||||
const uint8_t* extra;
|
||||
|
||||
/* superspeed endpoint companion */
|
||||
uint8_t bMaxBurst;
|
||||
uint8_t bmAttributes_super;
|
||||
uint16_t wBytesPerInterval;
|
||||
uint8_t bMaxBurst;
|
||||
uint8_t bmAttributes_super;
|
||||
uint16_t wBytesPerInterval;
|
||||
};
|
||||
|
||||
struct USBDescOther {
|
||||
uint8_t length;
|
||||
const uint8_t *data;
|
||||
struct USBDescOther
|
||||
{
|
||||
uint8_t length;
|
||||
const uint8_t* data;
|
||||
};
|
||||
|
||||
struct USBDescMSOS {
|
||||
const char *CompatibleID;
|
||||
const wchar_t *Label;
|
||||
bool SelectiveSuspendEnabled;
|
||||
struct USBDescMSOS
|
||||
{
|
||||
const char* CompatibleID;
|
||||
const wchar_t* Label;
|
||||
bool SelectiveSuspendEnabled;
|
||||
};
|
||||
|
||||
typedef const char *USBDescStrings[256];
|
||||
typedef const char* USBDescStrings[256];
|
||||
|
||||
struct USBDesc {
|
||||
USBDescID id;
|
||||
const USBDescDevice *full;
|
||||
const USBDescDevice *high;
|
||||
const USBDescDevice *super;
|
||||
const char* const *str;
|
||||
const USBDescMSOS *msos;
|
||||
struct USBDesc
|
||||
{
|
||||
USBDescID id;
|
||||
const USBDescDevice* full;
|
||||
const USBDescDevice* high;
|
||||
const USBDescDevice* super;
|
||||
const char* const* str;
|
||||
const USBDescMSOS* msos;
|
||||
};
|
||||
|
||||
#define USB_DESC_FLAG_SUPER (1 << 1)
|
||||
|
@ -229,32 +252,32 @@ static inline uint8_t usb_hi(uint16_t val)
|
|||
}
|
||||
|
||||
/* generate usb packages from structs */
|
||||
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
||||
bool msos, uint8_t *dest, size_t len);
|
||||
int usb_desc_device_qualifier(const USBDescDevice *dev,
|
||||
uint8_t *dest, size_t len);
|
||||
int usb_desc_device(const USBDescID* id, const USBDescDevice* dev,
|
||||
bool msos, uint8_t* dest, size_t len);
|
||||
int usb_desc_device_qualifier(const USBDescDevice* dev,
|
||||
uint8_t* dest, size_t len);
|
||||
int usb_desc_config(const USBDescConfig& conf, int flags,
|
||||
uint8_t *dest, size_t len);
|
||||
uint8_t* dest, size_t len);
|
||||
int usb_desc_iface_group(const USBDescIfaceAssoc& iad, int flags,
|
||||
uint8_t *dest, size_t len);
|
||||
uint8_t* dest, size_t len);
|
||||
int usb_desc_iface(const USBDescIface& iface, int flags,
|
||||
uint8_t *dest, size_t len);
|
||||
uint8_t* dest, size_t len);
|
||||
int usb_desc_endpoint(const USBDescEndpoint& ep, int flags,
|
||||
uint8_t *dest, size_t len);
|
||||
int usb_desc_other(const USBDescOther& desc, uint8_t *dest, size_t len);
|
||||
uint8_t* dest, size_t len);
|
||||
int usb_desc_other(const USBDescOther& desc, uint8_t* dest, size_t len);
|
||||
//int usb_desc_msos(const USBDesc *desc, USBPacket *p,
|
||||
// int index, uint8_t *dest, size_t len);
|
||||
int usb_desc_parse_dev (const uint8_t *data, int len, USBDesc& desc, USBDescDevice& dev);
|
||||
int usb_desc_parse_config (const uint8_t *data, int len, USBDescDevice& dev);
|
||||
int usb_desc_parse_dev(const uint8_t* data, int len, USBDesc& desc, USBDescDevice& dev);
|
||||
int usb_desc_parse_config(const uint8_t* data, int len, USBDescDevice& dev);
|
||||
|
||||
/* control message emulation helpers */
|
||||
void usb_desc_init(USBDevice *dev);
|
||||
void usb_desc_attach(USBDevice *dev);
|
||||
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
|
||||
int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
|
||||
int value, uint8_t *dest, size_t len);
|
||||
int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||
int request, int value, int index, int length, uint8_t *data);
|
||||
void usb_desc_init(USBDevice* dev);
|
||||
void usb_desc_attach(USBDevice* dev);
|
||||
int usb_desc_string(USBDevice* dev, int index, uint8_t* dest, size_t len);
|
||||
int usb_desc_get_descriptor(USBDevice* dev, USBPacket* p,
|
||||
int value, uint8_t* dest, size_t len);
|
||||
int usb_desc_handle_control(USBDevice* dev, USBPacket* p,
|
||||
int request, int value, int index, int length, uint8_t* data);
|
||||
|
||||
int usb_desc_set_config(USBDevice *dev, int value);
|
||||
int usb_desc_set_interface(USBDevice *dev, int index, int value);
|
||||
int usb_desc_set_config(USBDevice* dev, int value);
|
||||
int usb_desc_set_interface(USBDevice* dev, int index, int value);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
|
||||
#define SIZE_OVERFLOWS(a, b) (G_UNLIKELY((b) > 0 && (a) > G_MAXSIZE / (b)))
|
||||
|
||||
/**
|
||||
* g_malloc:
|
||||
|
@ -28,25 +28,24 @@
|
|||
*
|
||||
* 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))
|
||||
{
|
||||
void* mem;
|
||||
if (G_LIKELY(n_bytes))
|
||||
{
|
||||
void* mem;
|
||||
|
||||
mem = malloc (n_bytes);
|
||||
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
|
||||
if (mem)
|
||||
return mem;
|
||||
mem = malloc(n_bytes);
|
||||
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
|
||||
if (mem)
|
||||
return mem;
|
||||
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
|
||||
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
|
||||
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* g_malloc0:
|
||||
|
@ -57,25 +56,24 @@ 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))
|
||||
{
|
||||
void* mem;
|
||||
if (G_LIKELY(n_bytes))
|
||||
{
|
||||
void* mem;
|
||||
|
||||
mem = calloc (1, n_bytes);
|
||||
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
|
||||
if (mem)
|
||||
return mem;
|
||||
mem = calloc(1, n_bytes);
|
||||
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
|
||||
if (mem)
|
||||
return mem;
|
||||
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
|
||||
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0));
|
||||
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0));
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* g_malloc_n:
|
||||
|
@ -88,17 +86,16 @@ 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,
|
||||
size_t n_block_bytes)
|
||||
void* my_g_malloc_n(size_t n_blocks,
|
||||
size_t n_block_bytes)
|
||||
{
|
||||
if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
|
||||
{
|
||||
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_blocks, n_block_bytes);
|
||||
}
|
||||
if (SIZE_OVERFLOWS(n_blocks, n_block_bytes))
|
||||
{
|
||||
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_blocks, n_block_bytes);
|
||||
}
|
||||
|
||||
return my_g_malloc (n_blocks * n_block_bytes);
|
||||
return my_g_malloc(n_blocks * n_block_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,29 +111,28 @@ my_g_malloc_n (size_t n_blocks,
|
|||
*
|
||||
* Returns: the new address of the allocated memory
|
||||
*/
|
||||
void*
|
||||
my_g_realloc (void* mem,
|
||||
size_t n_bytes)
|
||||
void* my_g_realloc(void* mem,
|
||||
size_t n_bytes)
|
||||
{
|
||||
void* newmem;
|
||||
void* newmem;
|
||||
|
||||
if (G_LIKELY (n_bytes))
|
||||
{
|
||||
newmem = realloc (mem, n_bytes);
|
||||
//TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
|
||||
if (newmem)
|
||||
return newmem;
|
||||
if (G_LIKELY(n_bytes))
|
||||
{
|
||||
newmem = realloc(mem, n_bytes);
|
||||
//TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
|
||||
if (newmem)
|
||||
return newmem;
|
||||
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_bytes);
|
||||
}
|
||||
|
||||
if (mem)
|
||||
free (mem);
|
||||
if (mem)
|
||||
free(mem);
|
||||
|
||||
//TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
|
||||
//TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,16 +147,15 @@ my_g_realloc (void* mem,
|
|||
* Since: 2.24
|
||||
* Returns: the new address of the allocated memory
|
||||
*/
|
||||
void*
|
||||
my_g_realloc_n (void* mem,
|
||||
size_t n_blocks,
|
||||
size_t n_block_bytes)
|
||||
void* my_g_realloc_n(void* mem,
|
||||
size_t n_blocks,
|
||||
size_t n_block_bytes)
|
||||
{
|
||||
if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
|
||||
{
|
||||
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_blocks, n_block_bytes);
|
||||
}
|
||||
if (SIZE_OVERFLOWS(n_blocks, n_block_bytes))
|
||||
{
|
||||
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
|
||||
// G_STRLOC, n_blocks, n_block_bytes);
|
||||
}
|
||||
|
||||
return my_g_realloc (mem, n_blocks * n_block_bytes);
|
||||
return my_g_realloc(mem, n_blocks * n_block_bytes);
|
||||
}
|
||||
|
|
|
@ -24,16 +24,16 @@
|
|||
#define G_MAXSIZE G_MAXUINT32
|
||||
#endif
|
||||
|
||||
#define G_MAXUINT64 0xffffffffffffffffUL
|
||||
#define G_MAXUINT32 ((uint32_t)0xffffffff)
|
||||
#define G_MAXUINT64 0xffffffffffffffffUL
|
||||
#define G_MAXUINT32 ((uint32_t)0xffffffff)
|
||||
|
||||
void* my_g_malloc0 (size_t n_bytes);
|
||||
void* my_g_malloc (size_t n_bytes);
|
||||
void* my_g_malloc_n (size_t n_blocks,
|
||||
size_t n_block_bytes);
|
||||
void* my_g_realloc_n (void* mem,
|
||||
size_t n_blocks,
|
||||
size_t n_block_bytes);
|
||||
void* my_g_malloc0(size_t n_bytes);
|
||||
void* my_g_malloc(size_t n_bytes);
|
||||
void* my_g_malloc_n(size_t n_blocks,
|
||||
size_t n_block_bytes);
|
||||
void* my_g_realloc_n(void* mem,
|
||||
size_t n_blocks,
|
||||
size_t n_block_bytes);
|
||||
|
||||
#define my_g_free free
|
||||
|
||||
|
@ -41,11 +41,11 @@ void* my_g_realloc_n (void* mem,
|
|||
#define G_UNLIKELY(expr) (expr)
|
||||
|
||||
#define my_G_NEW(struct_type, n_structs, func) \
|
||||
((struct_type *) my_g_##func##_n ((n_structs), sizeof (struct_type)))
|
||||
((struct_type*)my_g_##func##_n((n_structs), sizeof(struct_type)))
|
||||
#define my_G_RENEW(struct_type, mem, n_structs, func) \
|
||||
((struct_type *) my_g_##func##_n (mem, (n_structs), sizeof (struct_type)))
|
||||
((struct_type*)my_g_##func##_n(mem, (n_structs), sizeof(struct_type)))
|
||||
|
||||
#define my_g_new(struct_type, n_structs) my_G_NEW (struct_type, n_structs, malloc)
|
||||
#define my_g_renew(struct_type, mem, n_structs) my_G_RENEW (struct_type, mem, n_structs, realloc)
|
||||
#define my_g_new(struct_type, n_structs) my_G_NEW(struct_type, n_structs, malloc)
|
||||
#define my_g_renew(struct_type, mem, n_structs) my_G_RENEW(struct_type, mem, n_structs, realloc)
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,12 +25,12 @@
|
|||
#define MOUSE_EVENT_MBUTTON 0x04
|
||||
/* identical to the ps/2 keyboard bits */
|
||||
#define QEMU_SCROLL_LOCK_LED (1 << 0)
|
||||
#define QEMU_NUM_LOCK_LED (1 << 1)
|
||||
#define QEMU_CAPS_LOCK_LED (1 << 2)
|
||||
#define QEMU_NUM_LOCK_LED (1 << 1)
|
||||
#define QEMU_CAPS_LOCK_LED (1 << 2)
|
||||
|
||||
#define HID_MOUSE 1
|
||||
#define HID_TABLET 2
|
||||
#define HID_KEYBOARD 3
|
||||
#define HID_MOUSE 1
|
||||
#define HID_TABLET 2
|
||||
#define HID_KEYBOARD 3
|
||||
|
||||
/* scancode without modifiers */
|
||||
#define SCANCODE_KEYMASK 0xff
|
||||
|
@ -38,171 +38,173 @@
|
|||
#define SCANCODE_KEYCODEMASK 0x7f
|
||||
|
||||
/* "grey" keys will usually need a 0xe0 prefix */
|
||||
#define SCANCODE_GREY 0x80
|
||||
#define SCANCODE_EMUL0 0xE0
|
||||
#define SCANCODE_EMUL1 0xE1
|
||||
#define SCANCODE_GREY 0x80
|
||||
#define SCANCODE_EMUL0 0xE0
|
||||
#define SCANCODE_EMUL1 0xE1
|
||||
/* "up" flag */
|
||||
#define SCANCODE_UP 0x80
|
||||
#define SCANCODE_UP 0x80
|
||||
|
||||
/* Additional modifiers to use if not catched another way. */
|
||||
#define SCANCODE_SHIFT 0x100
|
||||
#define SCANCODE_CTRL 0x200
|
||||
#define SCANCODE_ALT 0x400
|
||||
#define SCANCODE_ALTGR 0x800
|
||||
#define SCANCODE_SHIFT 0x100
|
||||
#define SCANCODE_CTRL 0x200
|
||||
#define SCANCODE_ALT 0x400
|
||||
#define SCANCODE_ALTGR 0x800
|
||||
|
||||
typedef enum QKeyCode {
|
||||
Q_KEY_CODE_UNMAPPED = 0,
|
||||
Q_KEY_CODE_SHIFT = 1,
|
||||
Q_KEY_CODE_SHIFT_R = 2,
|
||||
Q_KEY_CODE_ALT = 3,
|
||||
Q_KEY_CODE_ALT_R = 4,
|
||||
Q_KEY_CODE_CTRL = 5,
|
||||
Q_KEY_CODE_CTRL_R = 6,
|
||||
Q_KEY_CODE_MENU = 7,
|
||||
Q_KEY_CODE_ESC = 8,
|
||||
Q_KEY_CODE_1 = 9,
|
||||
Q_KEY_CODE_2 = 10,
|
||||
Q_KEY_CODE_3 = 11,
|
||||
Q_KEY_CODE_4 = 12,
|
||||
Q_KEY_CODE_5 = 13,
|
||||
Q_KEY_CODE_6 = 14,
|
||||
Q_KEY_CODE_7 = 15,
|
||||
Q_KEY_CODE_8 = 16,
|
||||
Q_KEY_CODE_9 = 17,
|
||||
Q_KEY_CODE_0 = 18,
|
||||
Q_KEY_CODE_MINUS = 19,
|
||||
Q_KEY_CODE_EQUAL = 20,
|
||||
Q_KEY_CODE_BACKSPACE = 21,
|
||||
Q_KEY_CODE_TAB = 22,
|
||||
Q_KEY_CODE_Q = 23,
|
||||
Q_KEY_CODE_W = 24,
|
||||
Q_KEY_CODE_E = 25,
|
||||
Q_KEY_CODE_R = 26,
|
||||
Q_KEY_CODE_T = 27,
|
||||
Q_KEY_CODE_Y = 28,
|
||||
Q_KEY_CODE_U = 29,
|
||||
Q_KEY_CODE_I = 30,
|
||||
Q_KEY_CODE_O = 31,
|
||||
Q_KEY_CODE_P = 32,
|
||||
Q_KEY_CODE_BRACKET_LEFT = 33,
|
||||
Q_KEY_CODE_BRACKET_RIGHT = 34,
|
||||
Q_KEY_CODE_RET = 35,
|
||||
Q_KEY_CODE_A = 36,
|
||||
Q_KEY_CODE_S = 37,
|
||||
Q_KEY_CODE_D = 38,
|
||||
Q_KEY_CODE_F = 39,
|
||||
Q_KEY_CODE_G = 40,
|
||||
Q_KEY_CODE_H = 41,
|
||||
Q_KEY_CODE_J = 42,
|
||||
Q_KEY_CODE_K = 43,
|
||||
Q_KEY_CODE_L = 44,
|
||||
Q_KEY_CODE_SEMICOLON = 45,
|
||||
Q_KEY_CODE_APOSTROPHE = 46,
|
||||
Q_KEY_CODE_GRAVE_ACCENT = 47,
|
||||
Q_KEY_CODE_BACKSLASH = 48,
|
||||
Q_KEY_CODE_Z = 49,
|
||||
Q_KEY_CODE_X = 50,
|
||||
Q_KEY_CODE_C = 51,
|
||||
Q_KEY_CODE_V = 52,
|
||||
Q_KEY_CODE_B = 53,
|
||||
Q_KEY_CODE_N = 54,
|
||||
Q_KEY_CODE_M = 55,
|
||||
Q_KEY_CODE_COMMA = 56,
|
||||
Q_KEY_CODE_DOT = 57,
|
||||
Q_KEY_CODE_SLASH = 58,
|
||||
Q_KEY_CODE_ASTERISK = 59,
|
||||
Q_KEY_CODE_SPC = 60,
|
||||
Q_KEY_CODE_CAPS_LOCK = 61,
|
||||
Q_KEY_CODE_F1 = 62,
|
||||
Q_KEY_CODE_F2 = 63,
|
||||
Q_KEY_CODE_F3 = 64,
|
||||
Q_KEY_CODE_F4 = 65,
|
||||
Q_KEY_CODE_F5 = 66,
|
||||
Q_KEY_CODE_F6 = 67,
|
||||
Q_KEY_CODE_F7 = 68,
|
||||
Q_KEY_CODE_F8 = 69,
|
||||
Q_KEY_CODE_F9 = 70,
|
||||
Q_KEY_CODE_F10 = 71,
|
||||
Q_KEY_CODE_NUM_LOCK = 72,
|
||||
Q_KEY_CODE_SCROLL_LOCK = 73,
|
||||
Q_KEY_CODE_KP_DIVIDE = 74,
|
||||
Q_KEY_CODE_KP_MULTIPLY = 75,
|
||||
Q_KEY_CODE_KP_SUBTRACT = 76,
|
||||
Q_KEY_CODE_KP_ADD = 77,
|
||||
Q_KEY_CODE_KP_ENTER = 78,
|
||||
Q_KEY_CODE_KP_DECIMAL = 79,
|
||||
Q_KEY_CODE_SYSRQ = 80,
|
||||
Q_KEY_CODE_KP_0 = 81,
|
||||
Q_KEY_CODE_KP_1 = 82,
|
||||
Q_KEY_CODE_KP_2 = 83,
|
||||
Q_KEY_CODE_KP_3 = 84,
|
||||
Q_KEY_CODE_KP_4 = 85,
|
||||
Q_KEY_CODE_KP_5 = 86,
|
||||
Q_KEY_CODE_KP_6 = 87,
|
||||
Q_KEY_CODE_KP_7 = 88,
|
||||
Q_KEY_CODE_KP_8 = 89,
|
||||
Q_KEY_CODE_KP_9 = 90,
|
||||
Q_KEY_CODE_LESS = 91,
|
||||
Q_KEY_CODE_F11 = 92,
|
||||
Q_KEY_CODE_F12 = 93,
|
||||
Q_KEY_CODE_PRINT = 94,
|
||||
Q_KEY_CODE_HOME = 95,
|
||||
Q_KEY_CODE_PGUP = 96,
|
||||
Q_KEY_CODE_PGDN = 97,
|
||||
Q_KEY_CODE_END = 98,
|
||||
Q_KEY_CODE_LEFT = 99,
|
||||
Q_KEY_CODE_UP = 100,
|
||||
Q_KEY_CODE_DOWN = 101,
|
||||
Q_KEY_CODE_RIGHT = 102,
|
||||
Q_KEY_CODE_INSERT = 103,
|
||||
Q_KEY_CODE_DELETE = 104,
|
||||
Q_KEY_CODE_STOP = 105,
|
||||
Q_KEY_CODE_AGAIN = 106,
|
||||
Q_KEY_CODE_PROPS = 107,
|
||||
Q_KEY_CODE_UNDO = 108,
|
||||
Q_KEY_CODE_FRONT = 109,
|
||||
Q_KEY_CODE_COPY = 110,
|
||||
Q_KEY_CODE_OPEN = 111,
|
||||
Q_KEY_CODE_PASTE = 112,
|
||||
Q_KEY_CODE_FIND = 113,
|
||||
Q_KEY_CODE_CUT = 114,
|
||||
Q_KEY_CODE_LF = 115,
|
||||
Q_KEY_CODE_HELP = 116,
|
||||
Q_KEY_CODE_META_L = 117,
|
||||
Q_KEY_CODE_META_R = 118,
|
||||
Q_KEY_CODE_COMPOSE = 119,
|
||||
Q_KEY_CODE_PAUSE = 120,
|
||||
Q_KEY_CODE_RO = 121,
|
||||
Q_KEY_CODE_HIRAGANA = 122,
|
||||
Q_KEY_CODE_HENKAN = 123,
|
||||
Q_KEY_CODE_YEN = 124,
|
||||
Q_KEY_CODE_MUHENKAN = 125,
|
||||
Q_KEY_CODE_KATAKANAHIRAGANA = 126,
|
||||
Q_KEY_CODE_KP_COMMA = 127,
|
||||
Q_KEY_CODE_KP_EQUALS = 128,
|
||||
Q_KEY_CODE_POWER = 129,
|
||||
Q_KEY_CODE_SLEEP = 130,
|
||||
Q_KEY_CODE_WAKE = 131,
|
||||
Q_KEY_CODE_AUDIONEXT = 132,
|
||||
Q_KEY_CODE_AUDIOPREV = 133,
|
||||
Q_KEY_CODE_AUDIOSTOP = 134,
|
||||
Q_KEY_CODE_AUDIOPLAY = 135,
|
||||
Q_KEY_CODE_AUDIOMUTE = 136,
|
||||
Q_KEY_CODE_VOLUMEUP = 137,
|
||||
Q_KEY_CODE_VOLUMEDOWN = 138,
|
||||
Q_KEY_CODE_MEDIASELECT = 139,
|
||||
Q_KEY_CODE_MAIL = 140,
|
||||
Q_KEY_CODE_CALCULATOR = 141,
|
||||
Q_KEY_CODE_COMPUTER = 142,
|
||||
Q_KEY_CODE_AC_HOME = 143,
|
||||
Q_KEY_CODE_AC_BACK = 144,
|
||||
Q_KEY_CODE_AC_FORWARD = 145,
|
||||
Q_KEY_CODE_AC_REFRESH = 146,
|
||||
Q_KEY_CODE_AC_BOOKMARKS = 147,
|
||||
Q_KEY_CODE__MAX = 148,
|
||||
typedef enum QKeyCode
|
||||
{
|
||||
Q_KEY_CODE_UNMAPPED = 0,
|
||||
Q_KEY_CODE_SHIFT = 1,
|
||||
Q_KEY_CODE_SHIFT_R = 2,
|
||||
Q_KEY_CODE_ALT = 3,
|
||||
Q_KEY_CODE_ALT_R = 4,
|
||||
Q_KEY_CODE_CTRL = 5,
|
||||
Q_KEY_CODE_CTRL_R = 6,
|
||||
Q_KEY_CODE_MENU = 7,
|
||||
Q_KEY_CODE_ESC = 8,
|
||||
Q_KEY_CODE_1 = 9,
|
||||
Q_KEY_CODE_2 = 10,
|
||||
Q_KEY_CODE_3 = 11,
|
||||
Q_KEY_CODE_4 = 12,
|
||||
Q_KEY_CODE_5 = 13,
|
||||
Q_KEY_CODE_6 = 14,
|
||||
Q_KEY_CODE_7 = 15,
|
||||
Q_KEY_CODE_8 = 16,
|
||||
Q_KEY_CODE_9 = 17,
|
||||
Q_KEY_CODE_0 = 18,
|
||||
Q_KEY_CODE_MINUS = 19,
|
||||
Q_KEY_CODE_EQUAL = 20,
|
||||
Q_KEY_CODE_BACKSPACE = 21,
|
||||
Q_KEY_CODE_TAB = 22,
|
||||
Q_KEY_CODE_Q = 23,
|
||||
Q_KEY_CODE_W = 24,
|
||||
Q_KEY_CODE_E = 25,
|
||||
Q_KEY_CODE_R = 26,
|
||||
Q_KEY_CODE_T = 27,
|
||||
Q_KEY_CODE_Y = 28,
|
||||
Q_KEY_CODE_U = 29,
|
||||
Q_KEY_CODE_I = 30,
|
||||
Q_KEY_CODE_O = 31,
|
||||
Q_KEY_CODE_P = 32,
|
||||
Q_KEY_CODE_BRACKET_LEFT = 33,
|
||||
Q_KEY_CODE_BRACKET_RIGHT = 34,
|
||||
Q_KEY_CODE_RET = 35,
|
||||
Q_KEY_CODE_A = 36,
|
||||
Q_KEY_CODE_S = 37,
|
||||
Q_KEY_CODE_D = 38,
|
||||
Q_KEY_CODE_F = 39,
|
||||
Q_KEY_CODE_G = 40,
|
||||
Q_KEY_CODE_H = 41,
|
||||
Q_KEY_CODE_J = 42,
|
||||
Q_KEY_CODE_K = 43,
|
||||
Q_KEY_CODE_L = 44,
|
||||
Q_KEY_CODE_SEMICOLON = 45,
|
||||
Q_KEY_CODE_APOSTROPHE = 46,
|
||||
Q_KEY_CODE_GRAVE_ACCENT = 47,
|
||||
Q_KEY_CODE_BACKSLASH = 48,
|
||||
Q_KEY_CODE_Z = 49,
|
||||
Q_KEY_CODE_X = 50,
|
||||
Q_KEY_CODE_C = 51,
|
||||
Q_KEY_CODE_V = 52,
|
||||
Q_KEY_CODE_B = 53,
|
||||
Q_KEY_CODE_N = 54,
|
||||
Q_KEY_CODE_M = 55,
|
||||
Q_KEY_CODE_COMMA = 56,
|
||||
Q_KEY_CODE_DOT = 57,
|
||||
Q_KEY_CODE_SLASH = 58,
|
||||
Q_KEY_CODE_ASTERISK = 59,
|
||||
Q_KEY_CODE_SPC = 60,
|
||||
Q_KEY_CODE_CAPS_LOCK = 61,
|
||||
Q_KEY_CODE_F1 = 62,
|
||||
Q_KEY_CODE_F2 = 63,
|
||||
Q_KEY_CODE_F3 = 64,
|
||||
Q_KEY_CODE_F4 = 65,
|
||||
Q_KEY_CODE_F5 = 66,
|
||||
Q_KEY_CODE_F6 = 67,
|
||||
Q_KEY_CODE_F7 = 68,
|
||||
Q_KEY_CODE_F8 = 69,
|
||||
Q_KEY_CODE_F9 = 70,
|
||||
Q_KEY_CODE_F10 = 71,
|
||||
Q_KEY_CODE_NUM_LOCK = 72,
|
||||
Q_KEY_CODE_SCROLL_LOCK = 73,
|
||||
Q_KEY_CODE_KP_DIVIDE = 74,
|
||||
Q_KEY_CODE_KP_MULTIPLY = 75,
|
||||
Q_KEY_CODE_KP_SUBTRACT = 76,
|
||||
Q_KEY_CODE_KP_ADD = 77,
|
||||
Q_KEY_CODE_KP_ENTER = 78,
|
||||
Q_KEY_CODE_KP_DECIMAL = 79,
|
||||
Q_KEY_CODE_SYSRQ = 80,
|
||||
Q_KEY_CODE_KP_0 = 81,
|
||||
Q_KEY_CODE_KP_1 = 82,
|
||||
Q_KEY_CODE_KP_2 = 83,
|
||||
Q_KEY_CODE_KP_3 = 84,
|
||||
Q_KEY_CODE_KP_4 = 85,
|
||||
Q_KEY_CODE_KP_5 = 86,
|
||||
Q_KEY_CODE_KP_6 = 87,
|
||||
Q_KEY_CODE_KP_7 = 88,
|
||||
Q_KEY_CODE_KP_8 = 89,
|
||||
Q_KEY_CODE_KP_9 = 90,
|
||||
Q_KEY_CODE_LESS = 91,
|
||||
Q_KEY_CODE_F11 = 92,
|
||||
Q_KEY_CODE_F12 = 93,
|
||||
Q_KEY_CODE_PRINT = 94,
|
||||
Q_KEY_CODE_HOME = 95,
|
||||
Q_KEY_CODE_PGUP = 96,
|
||||
Q_KEY_CODE_PGDN = 97,
|
||||
Q_KEY_CODE_END = 98,
|
||||
Q_KEY_CODE_LEFT = 99,
|
||||
Q_KEY_CODE_UP = 100,
|
||||
Q_KEY_CODE_DOWN = 101,
|
||||
Q_KEY_CODE_RIGHT = 102,
|
||||
Q_KEY_CODE_INSERT = 103,
|
||||
Q_KEY_CODE_DELETE = 104,
|
||||
Q_KEY_CODE_STOP = 105,
|
||||
Q_KEY_CODE_AGAIN = 106,
|
||||
Q_KEY_CODE_PROPS = 107,
|
||||
Q_KEY_CODE_UNDO = 108,
|
||||
Q_KEY_CODE_FRONT = 109,
|
||||
Q_KEY_CODE_COPY = 110,
|
||||
Q_KEY_CODE_OPEN = 111,
|
||||
Q_KEY_CODE_PASTE = 112,
|
||||
Q_KEY_CODE_FIND = 113,
|
||||
Q_KEY_CODE_CUT = 114,
|
||||
Q_KEY_CODE_LF = 115,
|
||||
Q_KEY_CODE_HELP = 116,
|
||||
Q_KEY_CODE_META_L = 117,
|
||||
Q_KEY_CODE_META_R = 118,
|
||||
Q_KEY_CODE_COMPOSE = 119,
|
||||
Q_KEY_CODE_PAUSE = 120,
|
||||
Q_KEY_CODE_RO = 121,
|
||||
Q_KEY_CODE_HIRAGANA = 122,
|
||||
Q_KEY_CODE_HENKAN = 123,
|
||||
Q_KEY_CODE_YEN = 124,
|
||||
Q_KEY_CODE_MUHENKAN = 125,
|
||||
Q_KEY_CODE_KATAKANAHIRAGANA = 126,
|
||||
Q_KEY_CODE_KP_COMMA = 127,
|
||||
Q_KEY_CODE_KP_EQUALS = 128,
|
||||
Q_KEY_CODE_POWER = 129,
|
||||
Q_KEY_CODE_SLEEP = 130,
|
||||
Q_KEY_CODE_WAKE = 131,
|
||||
Q_KEY_CODE_AUDIONEXT = 132,
|
||||
Q_KEY_CODE_AUDIOPREV = 133,
|
||||
Q_KEY_CODE_AUDIOSTOP = 134,
|
||||
Q_KEY_CODE_AUDIOPLAY = 135,
|
||||
Q_KEY_CODE_AUDIOMUTE = 136,
|
||||
Q_KEY_CODE_VOLUMEUP = 137,
|
||||
Q_KEY_CODE_VOLUMEDOWN = 138,
|
||||
Q_KEY_CODE_MEDIASELECT = 139,
|
||||
Q_KEY_CODE_MAIL = 140,
|
||||
Q_KEY_CODE_CALCULATOR = 141,
|
||||
Q_KEY_CODE_COMPUTER = 142,
|
||||
Q_KEY_CODE_AC_HOME = 143,
|
||||
Q_KEY_CODE_AC_BACK = 144,
|
||||
Q_KEY_CODE_AC_FORWARD = 145,
|
||||
Q_KEY_CODE_AC_REFRESH = 146,
|
||||
Q_KEY_CODE_AC_BOOKMARKS = 147,
|
||||
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;
|
||||
|
@ -267,61 +279,66 @@ struct InputEvent {
|
|||
};
|
||||
|
||||
typedef struct HIDState HIDState;
|
||||
typedef void(*HIDEventFunc)(HIDState *s);
|
||||
typedef void (*HIDEventFunc)(HIDState* s);
|
||||
|
||||
typedef void QEMUPutKBDEvent(HIDState *hs, InputEvent *evt);
|
||||
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
|
||||
typedef void QEMUPutMouseEvent(HIDState *hs, InputEvent *evt);
|
||||
typedef void QEMUPutKBDEvent(HIDState* hs, InputEvent* evt);
|
||||
typedef void QEMUPutLEDEvent(void* opaque, int ledstate);
|
||||
typedef void QEMUPutMouseEvent(HIDState* hs, InputEvent* evt);
|
||||
|
||||
typedef struct HIDPointerEvent {
|
||||
int32_t xdx, ydy; /* relative if it's a mouse, otherwise absolute */
|
||||
int32_t dz, buttons_state;
|
||||
typedef struct HIDPointerEvent
|
||||
{
|
||||
int32_t xdx, ydy; /* relative if it's a mouse, otherwise absolute */
|
||||
int32_t dz, buttons_state;
|
||||
} HIDPointerEvent;
|
||||
|
||||
#define QUEUE_LENGTH 16 /* should be enough for a triple-click */
|
||||
#define QUEUE_MASK (QUEUE_LENGTH-1u)
|
||||
#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
|
||||
#define QUEUE_LENGTH 16 /* should be enough for a triple-click */
|
||||
#define QUEUE_MASK (QUEUE_LENGTH - 1u)
|
||||
#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
|
||||
|
||||
typedef struct HIDMouseState {
|
||||
HIDPointerEvent queue[QUEUE_LENGTH];
|
||||
int mouse_grabbed;
|
||||
QEMUPutMouseEvent *eh_entry;
|
||||
HIDEventFunc eh_sync;
|
||||
typedef struct HIDMouseState
|
||||
{
|
||||
HIDPointerEvent queue[QUEUE_LENGTH];
|
||||
int mouse_grabbed;
|
||||
QEMUPutMouseEvent* eh_entry;
|
||||
HIDEventFunc eh_sync;
|
||||
} HIDMouseState;
|
||||
|
||||
typedef struct HIDKeyboardState {
|
||||
uint32_t keycodes[QUEUE_LENGTH];
|
||||
uint16_t modifiers;
|
||||
uint8_t leds;
|
||||
uint8_t key[16];
|
||||
int32_t keys;
|
||||
QEMUPutKBDEvent *eh_entry;
|
||||
typedef struct HIDKeyboardState
|
||||
{
|
||||
uint32_t keycodes[QUEUE_LENGTH];
|
||||
uint16_t modifiers;
|
||||
uint8_t leds;
|
||||
uint8_t key[16];
|
||||
int32_t keys;
|
||||
QEMUPutKBDEvent* eh_entry;
|
||||
} HIDKeyboardState;
|
||||
|
||||
struct HIDState {
|
||||
union {
|
||||
HIDMouseState ptr;
|
||||
HIDKeyboardState kbd;
|
||||
};
|
||||
uint32_t head; /* index into circular queue */
|
||||
uint32_t n;
|
||||
int kind;
|
||||
int32_t protocol;
|
||||
uint8_t idle;
|
||||
bool idle_pending;
|
||||
//QEMUTimer *idle_timer;
|
||||
HIDEventFunc event;
|
||||
struct HIDState
|
||||
{
|
||||
union
|
||||
{
|
||||
HIDMouseState ptr;
|
||||
HIDKeyboardState kbd;
|
||||
};
|
||||
uint32_t head; /* index into circular queue */
|
||||
uint32_t n;
|
||||
int kind;
|
||||
int32_t protocol;
|
||||
uint8_t idle;
|
||||
bool idle_pending;
|
||||
//QEMUTimer *idle_timer;
|
||||
HIDEventFunc event;
|
||||
};
|
||||
|
||||
void hid_init(HIDState *hs, int kind, HIDEventFunc event);
|
||||
void hid_reset(HIDState *hs);
|
||||
void hid_free(HIDState *hs);
|
||||
void hid_init(HIDState* hs, int kind, HIDEventFunc event);
|
||||
void hid_reset(HIDState* hs);
|
||||
void hid_free(HIDState* hs);
|
||||
|
||||
bool hid_has_events(HIDState *hs);
|
||||
void hid_set_next_idle(HIDState *hs);
|
||||
void hid_pointer_activate(HIDState *hs);
|
||||
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
|
||||
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
|
||||
int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len);
|
||||
bool hid_has_events(HIDState* hs);
|
||||
void hid_set_next_idle(HIDState* hs);
|
||||
void hid_pointer_activate(HIDState* hs);
|
||||
int hid_pointer_poll(HIDState* hs, uint8_t* buf, int len);
|
||||
int hid_keyboard_poll(HIDState* hs, uint8_t* buf, int len);
|
||||
int hid_keyboard_write(HIDState* hs, uint8_t* buf, int len);
|
||||
|
||||
#endif /* QEMU_HID_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,197 +17,202 @@
|
|||
|
||||
//TODO how much does std::map kill perf if any?
|
||||
const std::map<const QKeyCode, unsigned short> qemu_input_map_qcode_to_qnum = {
|
||||
{Q_KEY_CODE_0, 0xb}, /* qcode:Q_KEY_CODE_0 (0) -> linux:11 (KEY_0) -> qnum:11 */
|
||||
{Q_KEY_CODE_1, 0x2}, /* qcode:Q_KEY_CODE_1 (1) -> linux:2 (KEY_1) -> qnum:2 */
|
||||
{Q_KEY_CODE_2, 0x3}, /* qcode:Q_KEY_CODE_2 (2) -> linux:3 (KEY_2) -> qnum:3 */
|
||||
{Q_KEY_CODE_3, 0x4}, /* qcode:Q_KEY_CODE_3 (3) -> linux:4 (KEY_3) -> qnum:4 */
|
||||
{Q_KEY_CODE_4, 0x5}, /* qcode:Q_KEY_CODE_4 (4) -> linux:5 (KEY_4) -> qnum:5 */
|
||||
{Q_KEY_CODE_5, 0x6}, /* qcode:Q_KEY_CODE_5 (5) -> linux:6 (KEY_5) -> qnum:6 */
|
||||
{Q_KEY_CODE_6, 0x7}, /* qcode:Q_KEY_CODE_6 (6) -> linux:7 (KEY_6) -> qnum:7 */
|
||||
{Q_KEY_CODE_7, 0x8}, /* qcode:Q_KEY_CODE_7 (7) -> linux:8 (KEY_7) -> qnum:8 */
|
||||
{Q_KEY_CODE_8, 0x9}, /* qcode:Q_KEY_CODE_8 (8) -> linux:9 (KEY_8) -> qnum:9 */
|
||||
{Q_KEY_CODE_9, 0xa}, /* qcode:Q_KEY_CODE_9 (9) -> linux:10 (KEY_9) -> qnum:10 */
|
||||
{Q_KEY_CODE_A, 0x1e}, /* qcode:Q_KEY_CODE_A (a) -> linux:30 (KEY_A) -> qnum:30 */
|
||||
{Q_KEY_CODE_AC_BACK, 0xea}, /* qcode:Q_KEY_CODE_AC_BACK (ac_back) -> linux:158 (KEY_BACK) -> qnum:234 */
|
||||
{Q_KEY_CODE_AC_BOOKMARKS, 0xe6}, /* qcode:Q_KEY_CODE_AC_BOOKMARKS (ac_bookmarks) -> linux:156 (KEY_BOOKMARKS) -> qnum:230 */
|
||||
{Q_KEY_CODE_AC_FORWARD, 0xe9}, /* qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) -> linux:159 (KEY_FORWARD) -> qnum:233 */
|
||||
{Q_KEY_CODE_AC_HOME, 0xb2}, /* qcode:Q_KEY_CODE_AC_HOME (ac_home) -> linux:172 (KEY_HOMEPAGE) -> qnum:178 */
|
||||
{Q_KEY_CODE_AC_REFRESH, 0xe7}, /* qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) -> linux:173 (KEY_REFRESH) -> qnum:231 */
|
||||
{Q_KEY_CODE_AGAIN, 0x85}, /* qcode:Q_KEY_CODE_AGAIN (again) -> linux:129 (KEY_AGAIN) -> qnum:133 */
|
||||
{Q_KEY_CODE_ALT, 0x38}, /* qcode:Q_KEY_CODE_ALT (alt) -> linux:56 (KEY_LEFTALT) -> qnum:56 */
|
||||
{Q_KEY_CODE_ALT_R, 0xb8}, /* qcode:Q_KEY_CODE_ALT_R (alt_r) -> linux:100 (KEY_RIGHTALT) -> qnum:184 */
|
||||
{Q_KEY_CODE_APOSTROPHE, 0x28}, /* qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) -> linux:40 (KEY_APOSTROPHE) -> qnum:40 */
|
||||
{Q_KEY_CODE_ASTERISK, 0x37}, /* qcode:Q_KEY_CODE_ASTERISK (kp_multiply) -> linux:55 (KEY_KPASTERISK) -> qnum:55 */
|
||||
{Q_KEY_CODE_AUDIOMUTE, 0xa0}, /* qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) -> linux:113 (KEY_MUTE) -> qnum:160 */
|
||||
{Q_KEY_CODE_AUDIONEXT, 0x99}, /* qcode:Q_KEY_CODE_AUDIONEXT (audionext) -> linux:163 (KEY_NEXTSONG) -> qnum:153 */
|
||||
{Q_KEY_CODE_AUDIOPLAY, 0xa2}, /* qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) -> linux:164 (KEY_PLAYPAUSE) -> qnum:162 */
|
||||
{Q_KEY_CODE_AUDIOPREV, 0x90}, /* qcode:Q_KEY_CODE_AUDIOPREV (audioprev) -> linux:165 (KEY_PREVIOUSSONG) -> qnum:144 */
|
||||
{Q_KEY_CODE_AUDIOSTOP, 0xa4}, /* qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) -> linux:166 (KEY_STOPCD) -> qnum:164 */
|
||||
{Q_KEY_CODE_B, 0x30}, /* qcode:Q_KEY_CODE_B (b) -> linux:48 (KEY_B) -> qnum:48 */
|
||||
{Q_KEY_CODE_BACKSLASH, 0x2b}, /* qcode:Q_KEY_CODE_BACKSLASH (backslash) -> linux:43 (KEY_BACKSLASH) -> qnum:43 */
|
||||
{Q_KEY_CODE_BACKSPACE, 0xe}, /* qcode:Q_KEY_CODE_BACKSPACE (backspace) -> linux:14 (KEY_BACKSPACE) -> qnum:14 */
|
||||
{Q_KEY_CODE_BRACKET_LEFT, 0x1a}, /* qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) -> linux:26 (KEY_LEFTBRACE) -> qnum:26 */
|
||||
{Q_KEY_CODE_BRACKET_RIGHT, 0x1b}, /* qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) -> linux:27 (KEY_RIGHTBRACE) -> qnum:27 */
|
||||
{Q_KEY_CODE_C, 0x2e}, /* qcode:Q_KEY_CODE_C (c) -> linux:46 (KEY_C) -> qnum:46 */
|
||||
{Q_KEY_CODE_CALCULATOR, 0xa1}, /* qcode:Q_KEY_CODE_CALCULATOR (calculator) -> linux:140 (KEY_CALC) -> qnum:161 */
|
||||
{Q_KEY_CODE_CAPS_LOCK, 0x3a}, /* qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) -> linux:58 (KEY_CAPSLOCK) -> qnum:58 */
|
||||
{Q_KEY_CODE_COMMA, 0x33}, /* qcode:Q_KEY_CODE_COMMA (comma) -> linux:51 (KEY_COMMA) -> qnum:51 */
|
||||
{Q_KEY_CODE_COMPOSE, 0xdd}, /* qcode:Q_KEY_CODE_COMPOSE (compose) -> linux:127 (KEY_COMPOSE) -> qnum:221 */
|
||||
{Q_KEY_CODE_COMPUTER, 0xeb}, /* qcode:Q_KEY_CODE_COMPUTER (computer) -> linux:157 (KEY_COMPUTER) -> qnum:235 */
|
||||
{Q_KEY_CODE_COPY, 0xf8}, /* qcode:Q_KEY_CODE_COPY (copy) -> linux:133 (KEY_COPY) -> qnum:248 */
|
||||
{Q_KEY_CODE_CTRL, 0x1d}, /* qcode:Q_KEY_CODE_CTRL (ctrl) -> linux:29 (KEY_LEFTCTRL) -> qnum:29 */
|
||||
{Q_KEY_CODE_CTRL_R, 0x9d}, /* qcode:Q_KEY_CODE_CTRL_R (ctrl_r) -> linux:97 (KEY_RIGHTCTRL) -> qnum:157 */
|
||||
{Q_KEY_CODE_CUT, 0xbc}, /* qcode:Q_KEY_CODE_CUT (cut) -> linux:137 (KEY_CUT) -> qnum:188 */
|
||||
{Q_KEY_CODE_D, 0x20}, /* qcode:Q_KEY_CODE_D (d) -> linux:32 (KEY_D) -> qnum:32 */
|
||||
{Q_KEY_CODE_DELETE, 0xd3}, /* qcode:Q_KEY_CODE_DELETE (delete) -> linux:111 (KEY_DELETE) -> qnum:211 */
|
||||
{Q_KEY_CODE_DOT, 0x34}, /* qcode:Q_KEY_CODE_DOT (dot) -> linux:52 (KEY_DOT) -> qnum:52 */
|
||||
{Q_KEY_CODE_DOWN, 0xd0}, /* qcode:Q_KEY_CODE_DOWN (down) -> linux:108 (KEY_DOWN) -> qnum:208 */
|
||||
{Q_KEY_CODE_E, 0x12}, /* qcode:Q_KEY_CODE_E (e) -> linux:18 (KEY_E) -> qnum:18 */
|
||||
{Q_KEY_CODE_END, 0xcf}, /* qcode:Q_KEY_CODE_END (end) -> linux:107 (KEY_END) -> qnum:207 */
|
||||
{Q_KEY_CODE_EQUAL, 0xd}, /* qcode:Q_KEY_CODE_EQUAL (equal) -> linux:13 (KEY_EQUAL) -> qnum:13 */
|
||||
{Q_KEY_CODE_ESC, 0x1}, /* qcode:Q_KEY_CODE_ESC (esc) -> linux:1 (KEY_ESC) -> qnum:1 */
|
||||
{Q_KEY_CODE_F, 0x21}, /* qcode:Q_KEY_CODE_F (f) -> linux:33 (KEY_F) -> qnum:33 */
|
||||
{Q_KEY_CODE_F1, 0x3b}, /* qcode:Q_KEY_CODE_F1 (f1) -> linux:59 (KEY_F1) -> qnum:59 */
|
||||
{Q_KEY_CODE_F10, 0x44}, /* qcode:Q_KEY_CODE_F10 (f10) -> linux:68 (KEY_F10) -> qnum:68 */
|
||||
{Q_KEY_CODE_F11, 0x57}, /* qcode:Q_KEY_CODE_F11 (f11) -> linux:87 (KEY_F11) -> qnum:87 */
|
||||
{Q_KEY_CODE_F12, 0x58}, /* qcode:Q_KEY_CODE_F12 (f12) -> linux:88 (KEY_F12) -> qnum:88 */
|
||||
{Q_KEY_CODE_F2, 0x3c}, /* qcode:Q_KEY_CODE_F2 (f2) -> linux:60 (KEY_F2) -> qnum:60 */
|
||||
{Q_KEY_CODE_F3, 0x3d}, /* qcode:Q_KEY_CODE_F3 (f3) -> linux:61 (KEY_F3) -> qnum:61 */
|
||||
{Q_KEY_CODE_F4, 0x3e}, /* qcode:Q_KEY_CODE_F4 (f4) -> linux:62 (KEY_F4) -> qnum:62 */
|
||||
{Q_KEY_CODE_F5, 0x3f}, /* qcode:Q_KEY_CODE_F5 (f5) -> linux:63 (KEY_F5) -> qnum:63 */
|
||||
{Q_KEY_CODE_F6, 0x40}, /* qcode:Q_KEY_CODE_F6 (f6) -> linux:64 (KEY_F6) -> qnum:64 */
|
||||
{Q_KEY_CODE_F7, 0x41}, /* qcode:Q_KEY_CODE_F7 (f7) -> linux:65 (KEY_F7) -> qnum:65 */
|
||||
{Q_KEY_CODE_F8, 0x42}, /* qcode:Q_KEY_CODE_F8 (f8) -> linux:66 (KEY_F8) -> qnum:66 */
|
||||
{Q_KEY_CODE_F9, 0x43}, /* qcode:Q_KEY_CODE_F9 (f9) -> linux:67 (KEY_F9) -> qnum:67 */
|
||||
{Q_KEY_CODE_FIND, 0xc1}, /* qcode:Q_KEY_CODE_FIND (find) -> linux:136 (KEY_FIND) -> qnum:193 */
|
||||
{Q_KEY_CODE_FRONT, 0x8c}, /* qcode:Q_KEY_CODE_FRONT (front) -> linux:132 (KEY_FRONT) -> qnum:140 */
|
||||
{Q_KEY_CODE_G, 0x22}, /* qcode:Q_KEY_CODE_G (g) -> linux:34 (KEY_G) -> qnum:34 */
|
||||
{Q_KEY_CODE_GRAVE_ACCENT, 0x29}, /* qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) -> linux:41 (KEY_GRAVE) -> qnum:41 */
|
||||
{Q_KEY_CODE_H, 0x23}, /* qcode:Q_KEY_CODE_H (h) -> linux:35 (KEY_H) -> qnum:35 */
|
||||
{Q_KEY_CODE_HELP, 0xf5}, /* qcode:Q_KEY_CODE_HELP (help) -> linux:138 (KEY_HELP) -> qnum:245 */
|
||||
{Q_KEY_CODE_HENKAN, 0x79}, /* qcode:Q_KEY_CODE_HENKAN (henkan) -> linux:92 (KEY_HENKAN) -> qnum:121 */
|
||||
{Q_KEY_CODE_HIRAGANA, 0x77}, /* qcode:Q_KEY_CODE_HIRAGANA (hiragana) -> linux:91 (KEY_HIRAGANA) -> qnum:119 */
|
||||
{Q_KEY_CODE_HOME, 0xc7}, /* qcode:Q_KEY_CODE_HOME (home) -> linux:102 (KEY_HOME) -> qnum:199 */
|
||||
{Q_KEY_CODE_I, 0x17}, /* qcode:Q_KEY_CODE_I (i) -> linux:23 (KEY_I) -> qnum:23 */
|
||||
{Q_KEY_CODE_INSERT, 0xd2}, /* qcode:Q_KEY_CODE_INSERT (insert) -> linux:110 (KEY_INSERT) -> qnum:210 */
|
||||
{Q_KEY_CODE_J, 0x24}, /* qcode:Q_KEY_CODE_J (j) -> linux:36 (KEY_J) -> qnum:36 */
|
||||
{Q_KEY_CODE_K, 0x25}, /* qcode:Q_KEY_CODE_K (k) -> linux:37 (KEY_K) -> qnum:37 */
|
||||
{Q_KEY_CODE_KATAKANAHIRAGANA, 0x70}, /* qcode:Q_KEY_CODE_KATAKANAHIRAGANA (katakanahiragana) -> linux:93 (KEY_KATAKANAHIRAGANA) -> qnum:112 */
|
||||
{Q_KEY_CODE_KP_0, 0x52}, /* qcode:Q_KEY_CODE_KP_0 (kp_0) -> linux:82 (KEY_KP0) -> qnum:82 */
|
||||
{Q_KEY_CODE_KP_1, 0x4f}, /* qcode:Q_KEY_CODE_KP_1 (kp_1) -> linux:79 (KEY_KP1) -> qnum:79 */
|
||||
{Q_KEY_CODE_KP_2, 0x50}, /* qcode:Q_KEY_CODE_KP_2 (kp_2) -> linux:80 (KEY_KP2) -> qnum:80 */
|
||||
{Q_KEY_CODE_KP_3, 0x51}, /* qcode:Q_KEY_CODE_KP_3 (kp_3) -> linux:81 (KEY_KP3) -> qnum:81 */
|
||||
{Q_KEY_CODE_KP_4, 0x4b}, /* qcode:Q_KEY_CODE_KP_4 (kp_4) -> linux:75 (KEY_KP4) -> qnum:75 */
|
||||
{Q_KEY_CODE_KP_5, 0x4c}, /* qcode:Q_KEY_CODE_KP_5 (kp_5) -> linux:76 (KEY_KP5) -> qnum:76 */
|
||||
{Q_KEY_CODE_KP_6, 0x4d}, /* qcode:Q_KEY_CODE_KP_6 (kp_6) -> linux:77 (KEY_KP6) -> qnum:77 */
|
||||
{Q_KEY_CODE_KP_7, 0x47}, /* qcode:Q_KEY_CODE_KP_7 (kp_7) -> linux:71 (KEY_KP7) -> qnum:71 */
|
||||
{Q_KEY_CODE_KP_8, 0x48}, /* qcode:Q_KEY_CODE_KP_8 (kp_8) -> linux:72 (KEY_KP8) -> qnum:72 */
|
||||
{Q_KEY_CODE_KP_9, 0x49}, /* qcode:Q_KEY_CODE_KP_9 (kp_9) -> linux:73 (KEY_KP9) -> qnum:73 */
|
||||
{Q_KEY_CODE_KP_ADD, 0x4e}, /* qcode:Q_KEY_CODE_KP_ADD (kp_add) -> linux:78 (KEY_KPPLUS) -> qnum:78 */
|
||||
{Q_KEY_CODE_KP_COMMA, 0x7e}, /* qcode:Q_KEY_CODE_KP_COMMA (kp_comma) -> linux:121 (KEY_KPCOMMA) -> qnum:126 */
|
||||
{Q_KEY_CODE_KP_DECIMAL, 0x53}, /* qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) -> linux:83 (KEY_KPDOT) -> qnum:83 */
|
||||
{Q_KEY_CODE_KP_DIVIDE, 0xb5}, /* qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) -> linux:98 (KEY_KPSLASH) -> qnum:181 */
|
||||
{Q_KEY_CODE_KP_ENTER, 0x9c}, /* qcode:Q_KEY_CODE_KP_ENTER (kp_enter) -> linux:96 (KEY_KPENTER) -> qnum:156 */
|
||||
{Q_KEY_CODE_KP_EQUALS, 0x59}, /* qcode:Q_KEY_CODE_KP_EQUALS (kp_equals) -> linux:117 (KEY_KPEQUAL) -> qnum:89 */
|
||||
{Q_KEY_CODE_KP_MULTIPLY, 0x37}, /* qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) -> linux:55 (KEY_KPASTERISK) -> qnum:55 */
|
||||
{Q_KEY_CODE_KP_SUBTRACT, 0x4a}, /* qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) -> linux:74 (KEY_KPMINUS) -> qnum:74 */
|
||||
{Q_KEY_CODE_L, 0x26}, /* qcode:Q_KEY_CODE_L (l) -> linux:38 (KEY_L) -> qnum:38 */
|
||||
{Q_KEY_CODE_LEFT, 0xcb}, /* qcode:Q_KEY_CODE_LEFT (left) -> linux:105 (KEY_LEFT) -> qnum:203 */
|
||||
{Q_KEY_CODE_LESS, 0x56}, /* qcode:Q_KEY_CODE_LESS (less) -> linux:86 (KEY_102ND) -> qnum:86 */
|
||||
{Q_KEY_CODE_LF, 0x5b}, /* qcode:Q_KEY_CODE_LF (lf) -> linux:101 (KEY_LINEFEED) -> qnum:91 */
|
||||
{Q_KEY_CODE_M, 0x32}, /* qcode:Q_KEY_CODE_M (m) -> linux:50 (KEY_M) -> qnum:50 */
|
||||
{Q_KEY_CODE_MAIL, 0xec}, /* qcode:Q_KEY_CODE_MAIL (mail) -> linux:155 (KEY_MAIL) -> qnum:236 */
|
||||
{Q_KEY_CODE_MEDIASELECT, 0xed}, /* qcode:Q_KEY_CODE_MEDIASELECT (mediaselect) -> linux:226 (KEY_MEDIA) -> qnum:237 */
|
||||
{Q_KEY_CODE_MENU, 0x9e}, /* qcode:Q_KEY_CODE_MENU (menu) -> linux:139 (KEY_MENU) -> qnum:158 */
|
||||
{Q_KEY_CODE_META_L, 0xdb}, /* qcode:Q_KEY_CODE_META_L (meta_l) -> linux:125 (KEY_LEFTMETA) -> qnum:219 */
|
||||
{Q_KEY_CODE_META_R, 0xdc}, /* qcode:Q_KEY_CODE_META_R (meta_r) -> linux:126 (KEY_RIGHTMETA) -> qnum:220 */
|
||||
{Q_KEY_CODE_MINUS, 0xc}, /* qcode:Q_KEY_CODE_MINUS (minus) -> linux:12 (KEY_MINUS) -> qnum:12 */
|
||||
{Q_KEY_CODE_MUHENKAN, 0x7b}, /* qcode:Q_KEY_CODE_MUHENKAN (muhenkan) -> linux:94 (KEY_MUHENKAN) -> qnum:123 */
|
||||
{Q_KEY_CODE_N, 0x31}, /* qcode:Q_KEY_CODE_N (n) -> linux:49 (KEY_N) -> qnum:49 */
|
||||
{Q_KEY_CODE_NUM_LOCK, 0x45}, /* qcode:Q_KEY_CODE_NUM_LOCK (num_lock) -> linux:69 (KEY_NUMLOCK) -> qnum:69 */
|
||||
{Q_KEY_CODE_O, 0x18}, /* qcode:Q_KEY_CODE_O (o) -> linux:24 (KEY_O) -> qnum:24 */
|
||||
{Q_KEY_CODE_OPEN, 0x64}, /* qcode:Q_KEY_CODE_OPEN (open) -> linux:134 (KEY_OPEN) -> qnum:100 */
|
||||
{Q_KEY_CODE_P, 0x19}, /* qcode:Q_KEY_CODE_P (p) -> linux:25 (KEY_P) -> qnum:25 */
|
||||
{Q_KEY_CODE_PASTE, 0x65}, /* qcode:Q_KEY_CODE_PASTE (paste) -> linux:135 (KEY_PASTE) -> qnum:101 */
|
||||
{Q_KEY_CODE_PAUSE, 0xc6}, /* qcode:Q_KEY_CODE_PAUSE (pause) -> linux:119 (KEY_PAUSE) -> qnum:198 */
|
||||
{Q_KEY_CODE_PGDN, 0xd1}, /* qcode:Q_KEY_CODE_PGDN (pgdn) -> linux:109 (KEY_PAGEDOWN) -> qnum:209 */
|
||||
{Q_KEY_CODE_PGUP, 0xc9}, /* qcode:Q_KEY_CODE_PGUP (pgup) -> linux:104 (KEY_PAGEUP) -> qnum:201 */
|
||||
{Q_KEY_CODE_POWER, 0xde}, /* qcode:Q_KEY_CODE_POWER (power) -> linux:116 (KEY_POWER) -> qnum:222 */
|
||||
{Q_KEY_CODE_PRINT, 0x54}, /* qcode:Q_KEY_CODE_PRINT (sysrq) -> linux:99 (KEY_SYSRQ) -> qnum:84 */
|
||||
{Q_KEY_CODE_PROPS, 0x86}, /* qcode:Q_KEY_CODE_PROPS (props) -> linux:130 (KEY_PROPS) -> qnum:134 */
|
||||
{Q_KEY_CODE_Q, 0x10}, /* qcode:Q_KEY_CODE_Q (q) -> linux:16 (KEY_Q) -> qnum:16 */
|
||||
{Q_KEY_CODE_R, 0x13}, /* qcode:Q_KEY_CODE_R (r) -> linux:19 (KEY_R) -> qnum:19 */
|
||||
{Q_KEY_CODE_RET, 0x1c}, /* qcode:Q_KEY_CODE_RET (ret) -> linux:28 (KEY_ENTER) -> qnum:28 */
|
||||
{Q_KEY_CODE_RIGHT, 0xcd}, /* qcode:Q_KEY_CODE_RIGHT (right) -> linux:106 (KEY_RIGHT) -> qnum:205 */
|
||||
{Q_KEY_CODE_RO, 0x73}, /* qcode:Q_KEY_CODE_RO (ro) -> linux:89 (KEY_RO) -> qnum:115 */
|
||||
{Q_KEY_CODE_S, 0x1f}, /* qcode:Q_KEY_CODE_S (s) -> linux:31 (KEY_S) -> qnum:31 */
|
||||
{Q_KEY_CODE_SCROLL_LOCK, 0x46}, /* qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) -> linux:70 (KEY_SCROLLLOCK) -> qnum:70 */
|
||||
{Q_KEY_CODE_SEMICOLON, 0x27}, /* qcode:Q_KEY_CODE_SEMICOLON (semicolon) -> linux:39 (KEY_SEMICOLON) -> qnum:39 */
|
||||
{Q_KEY_CODE_SHIFT, 0x2a}, /* qcode:Q_KEY_CODE_SHIFT (shift) -> linux:42 (KEY_LEFTSHIFT) -> qnum:42 */
|
||||
{Q_KEY_CODE_SHIFT_R, 0x36}, /* qcode:Q_KEY_CODE_SHIFT_R (shift_r) -> linux:54 (KEY_RIGHTSHIFT) -> qnum:54 */
|
||||
{Q_KEY_CODE_SLASH, 0x35}, /* qcode:Q_KEY_CODE_SLASH (slash) -> linux:53 (KEY_SLASH) -> qnum:53 */
|
||||
{Q_KEY_CODE_SLEEP, 0xdf}, /* qcode:Q_KEY_CODE_SLEEP (sleep) -> linux:142 (KEY_SLEEP) -> qnum:223 */
|
||||
{Q_KEY_CODE_SPC, 0x39}, /* qcode:Q_KEY_CODE_SPC (spc) -> linux:57 (KEY_SPACE) -> qnum:57 */
|
||||
{Q_KEY_CODE_STOP, 0xe8}, /* qcode:Q_KEY_CODE_STOP (stop) -> linux:128 (KEY_STOP) -> qnum:232 */
|
||||
{Q_KEY_CODE_SYSRQ, 0x54}, /* qcode:Q_KEY_CODE_SYSRQ (sysrq) -> linux:99 (KEY_SYSRQ) -> qnum:84 */
|
||||
{Q_KEY_CODE_T, 0x14}, /* qcode:Q_KEY_CODE_T (t) -> linux:20 (KEY_T) -> qnum:20 */
|
||||
{Q_KEY_CODE_TAB, 0xf}, /* qcode:Q_KEY_CODE_TAB (tab) -> linux:15 (KEY_TAB) -> qnum:15 */
|
||||
{Q_KEY_CODE_U, 0x16}, /* qcode:Q_KEY_CODE_U (u) -> linux:22 (KEY_U) -> qnum:22 */
|
||||
{Q_KEY_CODE_UNDO, 0x87}, /* qcode:Q_KEY_CODE_UNDO (undo) -> linux:131 (KEY_UNDO) -> qnum:135 */
|
||||
{Q_KEY_CODE_UP, 0xc8}, /* qcode:Q_KEY_CODE_UP (up) -> linux:103 (KEY_UP) -> qnum:200 */
|
||||
{Q_KEY_CODE_V, 0x2f}, /* qcode:Q_KEY_CODE_V (v) -> linux:47 (KEY_V) -> qnum:47 */
|
||||
{Q_KEY_CODE_VOLUMEDOWN, 0xae}, /* qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) -> linux:114 (KEY_VOLUMEDOWN) -> qnum:174 */
|
||||
{Q_KEY_CODE_VOLUMEUP, 0xb0}, /* qcode:Q_KEY_CODE_VOLUMEUP (volumeup) -> linux:115 (KEY_VOLUMEUP) -> qnum:176 */
|
||||
{Q_KEY_CODE_W, 0x11}, /* qcode:Q_KEY_CODE_W (w) -> linux:17 (KEY_W) -> qnum:17 */
|
||||
{Q_KEY_CODE_WAKE, 0xe3}, /* qcode:Q_KEY_CODE_WAKE (wake) -> linux:143 (KEY_WAKEUP) -> qnum:227 */
|
||||
{Q_KEY_CODE_X, 0x2d}, /* qcode:Q_KEY_CODE_X (x) -> linux:45 (KEY_X) -> qnum:45 */
|
||||
{Q_KEY_CODE_Y, 0x15}, /* qcode:Q_KEY_CODE_Y (y) -> linux:21 (KEY_Y) -> qnum:21 */
|
||||
{Q_KEY_CODE_YEN, 0x7d}, /* qcode:Q_KEY_CODE_YEN (yen) -> linux:124 (KEY_YEN) -> qnum:125 */
|
||||
{Q_KEY_CODE_Z, 0x2c}, /* qcode:Q_KEY_CODE_Z (z) -> linux:44 (KEY_Z) -> qnum:44 */
|
||||
{Q_KEY_CODE_0, 0xb}, /* qcode:Q_KEY_CODE_0 (0) -> linux:11 (KEY_0) -> qnum:11 */
|
||||
{Q_KEY_CODE_1, 0x2}, /* qcode:Q_KEY_CODE_1 (1) -> linux:2 (KEY_1) -> qnum:2 */
|
||||
{Q_KEY_CODE_2, 0x3}, /* qcode:Q_KEY_CODE_2 (2) -> linux:3 (KEY_2) -> qnum:3 */
|
||||
{Q_KEY_CODE_3, 0x4}, /* qcode:Q_KEY_CODE_3 (3) -> linux:4 (KEY_3) -> qnum:4 */
|
||||
{Q_KEY_CODE_4, 0x5}, /* qcode:Q_KEY_CODE_4 (4) -> linux:5 (KEY_4) -> qnum:5 */
|
||||
{Q_KEY_CODE_5, 0x6}, /* qcode:Q_KEY_CODE_5 (5) -> linux:6 (KEY_5) -> qnum:6 */
|
||||
{Q_KEY_CODE_6, 0x7}, /* qcode:Q_KEY_CODE_6 (6) -> linux:7 (KEY_6) -> qnum:7 */
|
||||
{Q_KEY_CODE_7, 0x8}, /* qcode:Q_KEY_CODE_7 (7) -> linux:8 (KEY_7) -> qnum:8 */
|
||||
{Q_KEY_CODE_8, 0x9}, /* qcode:Q_KEY_CODE_8 (8) -> linux:9 (KEY_8) -> qnum:9 */
|
||||
{Q_KEY_CODE_9, 0xa}, /* qcode:Q_KEY_CODE_9 (9) -> linux:10 (KEY_9) -> qnum:10 */
|
||||
{Q_KEY_CODE_A, 0x1e}, /* qcode:Q_KEY_CODE_A (a) -> linux:30 (KEY_A) -> qnum:30 */
|
||||
{Q_KEY_CODE_AC_BACK, 0xea}, /* qcode:Q_KEY_CODE_AC_BACK (ac_back) -> linux:158 (KEY_BACK) -> qnum:234 */
|
||||
{Q_KEY_CODE_AC_BOOKMARKS, 0xe6}, /* qcode:Q_KEY_CODE_AC_BOOKMARKS (ac_bookmarks) -> linux:156 (KEY_BOOKMARKS) -> qnum:230 */
|
||||
{Q_KEY_CODE_AC_FORWARD, 0xe9}, /* qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) -> linux:159 (KEY_FORWARD) -> qnum:233 */
|
||||
{Q_KEY_CODE_AC_HOME, 0xb2}, /* qcode:Q_KEY_CODE_AC_HOME (ac_home) -> linux:172 (KEY_HOMEPAGE) -> qnum:178 */
|
||||
{Q_KEY_CODE_AC_REFRESH, 0xe7}, /* qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) -> linux:173 (KEY_REFRESH) -> qnum:231 */
|
||||
{Q_KEY_CODE_AGAIN, 0x85}, /* qcode:Q_KEY_CODE_AGAIN (again) -> linux:129 (KEY_AGAIN) -> qnum:133 */
|
||||
{Q_KEY_CODE_ALT, 0x38}, /* qcode:Q_KEY_CODE_ALT (alt) -> linux:56 (KEY_LEFTALT) -> qnum:56 */
|
||||
{Q_KEY_CODE_ALT_R, 0xb8}, /* qcode:Q_KEY_CODE_ALT_R (alt_r) -> linux:100 (KEY_RIGHTALT) -> qnum:184 */
|
||||
{Q_KEY_CODE_APOSTROPHE, 0x28}, /* qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) -> linux:40 (KEY_APOSTROPHE) -> qnum:40 */
|
||||
{Q_KEY_CODE_ASTERISK, 0x37}, /* qcode:Q_KEY_CODE_ASTERISK (kp_multiply) -> linux:55 (KEY_KPASTERISK) -> qnum:55 */
|
||||
{Q_KEY_CODE_AUDIOMUTE, 0xa0}, /* qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) -> linux:113 (KEY_MUTE) -> qnum:160 */
|
||||
{Q_KEY_CODE_AUDIONEXT, 0x99}, /* qcode:Q_KEY_CODE_AUDIONEXT (audionext) -> linux:163 (KEY_NEXTSONG) -> qnum:153 */
|
||||
{Q_KEY_CODE_AUDIOPLAY, 0xa2}, /* qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) -> linux:164 (KEY_PLAYPAUSE) -> qnum:162 */
|
||||
{Q_KEY_CODE_AUDIOPREV, 0x90}, /* qcode:Q_KEY_CODE_AUDIOPREV (audioprev) -> linux:165 (KEY_PREVIOUSSONG) -> qnum:144 */
|
||||
{Q_KEY_CODE_AUDIOSTOP, 0xa4}, /* qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) -> linux:166 (KEY_STOPCD) -> qnum:164 */
|
||||
{Q_KEY_CODE_B, 0x30}, /* qcode:Q_KEY_CODE_B (b) -> linux:48 (KEY_B) -> qnum:48 */
|
||||
{Q_KEY_CODE_BACKSLASH, 0x2b}, /* qcode:Q_KEY_CODE_BACKSLASH (backslash) -> linux:43 (KEY_BACKSLASH) -> qnum:43 */
|
||||
{Q_KEY_CODE_BACKSPACE, 0xe}, /* qcode:Q_KEY_CODE_BACKSPACE (backspace) -> linux:14 (KEY_BACKSPACE) -> qnum:14 */
|
||||
{Q_KEY_CODE_BRACKET_LEFT, 0x1a}, /* qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) -> linux:26 (KEY_LEFTBRACE) -> qnum:26 */
|
||||
{Q_KEY_CODE_BRACKET_RIGHT, 0x1b}, /* qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) -> linux:27 (KEY_RIGHTBRACE) -> qnum:27 */
|
||||
{Q_KEY_CODE_C, 0x2e}, /* qcode:Q_KEY_CODE_C (c) -> linux:46 (KEY_C) -> qnum:46 */
|
||||
{Q_KEY_CODE_CALCULATOR, 0xa1}, /* qcode:Q_KEY_CODE_CALCULATOR (calculator) -> linux:140 (KEY_CALC) -> qnum:161 */
|
||||
{Q_KEY_CODE_CAPS_LOCK, 0x3a}, /* qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) -> linux:58 (KEY_CAPSLOCK) -> qnum:58 */
|
||||
{Q_KEY_CODE_COMMA, 0x33}, /* qcode:Q_KEY_CODE_COMMA (comma) -> linux:51 (KEY_COMMA) -> qnum:51 */
|
||||
{Q_KEY_CODE_COMPOSE, 0xdd}, /* qcode:Q_KEY_CODE_COMPOSE (compose) -> linux:127 (KEY_COMPOSE) -> qnum:221 */
|
||||
{Q_KEY_CODE_COMPUTER, 0xeb}, /* qcode:Q_KEY_CODE_COMPUTER (computer) -> linux:157 (KEY_COMPUTER) -> qnum:235 */
|
||||
{Q_KEY_CODE_COPY, 0xf8}, /* qcode:Q_KEY_CODE_COPY (copy) -> linux:133 (KEY_COPY) -> qnum:248 */
|
||||
{Q_KEY_CODE_CTRL, 0x1d}, /* qcode:Q_KEY_CODE_CTRL (ctrl) -> linux:29 (KEY_LEFTCTRL) -> qnum:29 */
|
||||
{Q_KEY_CODE_CTRL_R, 0x9d}, /* qcode:Q_KEY_CODE_CTRL_R (ctrl_r) -> linux:97 (KEY_RIGHTCTRL) -> qnum:157 */
|
||||
{Q_KEY_CODE_CUT, 0xbc}, /* qcode:Q_KEY_CODE_CUT (cut) -> linux:137 (KEY_CUT) -> qnum:188 */
|
||||
{Q_KEY_CODE_D, 0x20}, /* qcode:Q_KEY_CODE_D (d) -> linux:32 (KEY_D) -> qnum:32 */
|
||||
{Q_KEY_CODE_DELETE, 0xd3}, /* qcode:Q_KEY_CODE_DELETE (delete) -> linux:111 (KEY_DELETE) -> qnum:211 */
|
||||
{Q_KEY_CODE_DOT, 0x34}, /* qcode:Q_KEY_CODE_DOT (dot) -> linux:52 (KEY_DOT) -> qnum:52 */
|
||||
{Q_KEY_CODE_DOWN, 0xd0}, /* qcode:Q_KEY_CODE_DOWN (down) -> linux:108 (KEY_DOWN) -> qnum:208 */
|
||||
{Q_KEY_CODE_E, 0x12}, /* qcode:Q_KEY_CODE_E (e) -> linux:18 (KEY_E) -> qnum:18 */
|
||||
{Q_KEY_CODE_END, 0xcf}, /* qcode:Q_KEY_CODE_END (end) -> linux:107 (KEY_END) -> qnum:207 */
|
||||
{Q_KEY_CODE_EQUAL, 0xd}, /* qcode:Q_KEY_CODE_EQUAL (equal) -> linux:13 (KEY_EQUAL) -> qnum:13 */
|
||||
{Q_KEY_CODE_ESC, 0x1}, /* qcode:Q_KEY_CODE_ESC (esc) -> linux:1 (KEY_ESC) -> qnum:1 */
|
||||
{Q_KEY_CODE_F, 0x21}, /* qcode:Q_KEY_CODE_F (f) -> linux:33 (KEY_F) -> qnum:33 */
|
||||
{Q_KEY_CODE_F1, 0x3b}, /* qcode:Q_KEY_CODE_F1 (f1) -> linux:59 (KEY_F1) -> qnum:59 */
|
||||
{Q_KEY_CODE_F10, 0x44}, /* qcode:Q_KEY_CODE_F10 (f10) -> linux:68 (KEY_F10) -> qnum:68 */
|
||||
{Q_KEY_CODE_F11, 0x57}, /* qcode:Q_KEY_CODE_F11 (f11) -> linux:87 (KEY_F11) -> qnum:87 */
|
||||
{Q_KEY_CODE_F12, 0x58}, /* qcode:Q_KEY_CODE_F12 (f12) -> linux:88 (KEY_F12) -> qnum:88 */
|
||||
{Q_KEY_CODE_F2, 0x3c}, /* qcode:Q_KEY_CODE_F2 (f2) -> linux:60 (KEY_F2) -> qnum:60 */
|
||||
{Q_KEY_CODE_F3, 0x3d}, /* qcode:Q_KEY_CODE_F3 (f3) -> linux:61 (KEY_F3) -> qnum:61 */
|
||||
{Q_KEY_CODE_F4, 0x3e}, /* qcode:Q_KEY_CODE_F4 (f4) -> linux:62 (KEY_F4) -> qnum:62 */
|
||||
{Q_KEY_CODE_F5, 0x3f}, /* qcode:Q_KEY_CODE_F5 (f5) -> linux:63 (KEY_F5) -> qnum:63 */
|
||||
{Q_KEY_CODE_F6, 0x40}, /* qcode:Q_KEY_CODE_F6 (f6) -> linux:64 (KEY_F6) -> qnum:64 */
|
||||
{Q_KEY_CODE_F7, 0x41}, /* qcode:Q_KEY_CODE_F7 (f7) -> linux:65 (KEY_F7) -> qnum:65 */
|
||||
{Q_KEY_CODE_F8, 0x42}, /* qcode:Q_KEY_CODE_F8 (f8) -> linux:66 (KEY_F8) -> qnum:66 */
|
||||
{Q_KEY_CODE_F9, 0x43}, /* qcode:Q_KEY_CODE_F9 (f9) -> linux:67 (KEY_F9) -> qnum:67 */
|
||||
{Q_KEY_CODE_FIND, 0xc1}, /* qcode:Q_KEY_CODE_FIND (find) -> linux:136 (KEY_FIND) -> qnum:193 */
|
||||
{Q_KEY_CODE_FRONT, 0x8c}, /* qcode:Q_KEY_CODE_FRONT (front) -> linux:132 (KEY_FRONT) -> qnum:140 */
|
||||
{Q_KEY_CODE_G, 0x22}, /* qcode:Q_KEY_CODE_G (g) -> linux:34 (KEY_G) -> qnum:34 */
|
||||
{Q_KEY_CODE_GRAVE_ACCENT, 0x29}, /* qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) -> linux:41 (KEY_GRAVE) -> qnum:41 */
|
||||
{Q_KEY_CODE_H, 0x23}, /* qcode:Q_KEY_CODE_H (h) -> linux:35 (KEY_H) -> qnum:35 */
|
||||
{Q_KEY_CODE_HELP, 0xf5}, /* qcode:Q_KEY_CODE_HELP (help) -> linux:138 (KEY_HELP) -> qnum:245 */
|
||||
{Q_KEY_CODE_HENKAN, 0x79}, /* qcode:Q_KEY_CODE_HENKAN (henkan) -> linux:92 (KEY_HENKAN) -> qnum:121 */
|
||||
{Q_KEY_CODE_HIRAGANA, 0x77}, /* qcode:Q_KEY_CODE_HIRAGANA (hiragana) -> linux:91 (KEY_HIRAGANA) -> qnum:119 */
|
||||
{Q_KEY_CODE_HOME, 0xc7}, /* qcode:Q_KEY_CODE_HOME (home) -> linux:102 (KEY_HOME) -> qnum:199 */
|
||||
{Q_KEY_CODE_I, 0x17}, /* qcode:Q_KEY_CODE_I (i) -> linux:23 (KEY_I) -> qnum:23 */
|
||||
{Q_KEY_CODE_INSERT, 0xd2}, /* qcode:Q_KEY_CODE_INSERT (insert) -> linux:110 (KEY_INSERT) -> qnum:210 */
|
||||
{Q_KEY_CODE_J, 0x24}, /* qcode:Q_KEY_CODE_J (j) -> linux:36 (KEY_J) -> qnum:36 */
|
||||
{Q_KEY_CODE_K, 0x25}, /* qcode:Q_KEY_CODE_K (k) -> linux:37 (KEY_K) -> qnum:37 */
|
||||
{Q_KEY_CODE_KATAKANAHIRAGANA, 0x70}, /* qcode:Q_KEY_CODE_KATAKANAHIRAGANA (katakanahiragana) -> linux:93 (KEY_KATAKANAHIRAGANA) -> qnum:112 */
|
||||
{Q_KEY_CODE_KP_0, 0x52}, /* qcode:Q_KEY_CODE_KP_0 (kp_0) -> linux:82 (KEY_KP0) -> qnum:82 */
|
||||
{Q_KEY_CODE_KP_1, 0x4f}, /* qcode:Q_KEY_CODE_KP_1 (kp_1) -> linux:79 (KEY_KP1) -> qnum:79 */
|
||||
{Q_KEY_CODE_KP_2, 0x50}, /* qcode:Q_KEY_CODE_KP_2 (kp_2) -> linux:80 (KEY_KP2) -> qnum:80 */
|
||||
{Q_KEY_CODE_KP_3, 0x51}, /* qcode:Q_KEY_CODE_KP_3 (kp_3) -> linux:81 (KEY_KP3) -> qnum:81 */
|
||||
{Q_KEY_CODE_KP_4, 0x4b}, /* qcode:Q_KEY_CODE_KP_4 (kp_4) -> linux:75 (KEY_KP4) -> qnum:75 */
|
||||
{Q_KEY_CODE_KP_5, 0x4c}, /* qcode:Q_KEY_CODE_KP_5 (kp_5) -> linux:76 (KEY_KP5) -> qnum:76 */
|
||||
{Q_KEY_CODE_KP_6, 0x4d}, /* qcode:Q_KEY_CODE_KP_6 (kp_6) -> linux:77 (KEY_KP6) -> qnum:77 */
|
||||
{Q_KEY_CODE_KP_7, 0x47}, /* qcode:Q_KEY_CODE_KP_7 (kp_7) -> linux:71 (KEY_KP7) -> qnum:71 */
|
||||
{Q_KEY_CODE_KP_8, 0x48}, /* qcode:Q_KEY_CODE_KP_8 (kp_8) -> linux:72 (KEY_KP8) -> qnum:72 */
|
||||
{Q_KEY_CODE_KP_9, 0x49}, /* qcode:Q_KEY_CODE_KP_9 (kp_9) -> linux:73 (KEY_KP9) -> qnum:73 */
|
||||
{Q_KEY_CODE_KP_ADD, 0x4e}, /* qcode:Q_KEY_CODE_KP_ADD (kp_add) -> linux:78 (KEY_KPPLUS) -> qnum:78 */
|
||||
{Q_KEY_CODE_KP_COMMA, 0x7e}, /* qcode:Q_KEY_CODE_KP_COMMA (kp_comma) -> linux:121 (KEY_KPCOMMA) -> qnum:126 */
|
||||
{Q_KEY_CODE_KP_DECIMAL, 0x53}, /* qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) -> linux:83 (KEY_KPDOT) -> qnum:83 */
|
||||
{Q_KEY_CODE_KP_DIVIDE, 0xb5}, /* qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) -> linux:98 (KEY_KPSLASH) -> qnum:181 */
|
||||
{Q_KEY_CODE_KP_ENTER, 0x9c}, /* qcode:Q_KEY_CODE_KP_ENTER (kp_enter) -> linux:96 (KEY_KPENTER) -> qnum:156 */
|
||||
{Q_KEY_CODE_KP_EQUALS, 0x59}, /* qcode:Q_KEY_CODE_KP_EQUALS (kp_equals) -> linux:117 (KEY_KPEQUAL) -> qnum:89 */
|
||||
{Q_KEY_CODE_KP_MULTIPLY, 0x37}, /* qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) -> linux:55 (KEY_KPASTERISK) -> qnum:55 */
|
||||
{Q_KEY_CODE_KP_SUBTRACT, 0x4a}, /* qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) -> linux:74 (KEY_KPMINUS) -> qnum:74 */
|
||||
{Q_KEY_CODE_L, 0x26}, /* qcode:Q_KEY_CODE_L (l) -> linux:38 (KEY_L) -> qnum:38 */
|
||||
{Q_KEY_CODE_LEFT, 0xcb}, /* qcode:Q_KEY_CODE_LEFT (left) -> linux:105 (KEY_LEFT) -> qnum:203 */
|
||||
{Q_KEY_CODE_LESS, 0x56}, /* qcode:Q_KEY_CODE_LESS (less) -> linux:86 (KEY_102ND) -> qnum:86 */
|
||||
{Q_KEY_CODE_LF, 0x5b}, /* qcode:Q_KEY_CODE_LF (lf) -> linux:101 (KEY_LINEFEED) -> qnum:91 */
|
||||
{Q_KEY_CODE_M, 0x32}, /* qcode:Q_KEY_CODE_M (m) -> linux:50 (KEY_M) -> qnum:50 */
|
||||
{Q_KEY_CODE_MAIL, 0xec}, /* qcode:Q_KEY_CODE_MAIL (mail) -> linux:155 (KEY_MAIL) -> qnum:236 */
|
||||
{Q_KEY_CODE_MEDIASELECT, 0xed}, /* qcode:Q_KEY_CODE_MEDIASELECT (mediaselect) -> linux:226 (KEY_MEDIA) -> qnum:237 */
|
||||
{Q_KEY_CODE_MENU, 0x9e}, /* qcode:Q_KEY_CODE_MENU (menu) -> linux:139 (KEY_MENU) -> qnum:158 */
|
||||
{Q_KEY_CODE_META_L, 0xdb}, /* qcode:Q_KEY_CODE_META_L (meta_l) -> linux:125 (KEY_LEFTMETA) -> qnum:219 */
|
||||
{Q_KEY_CODE_META_R, 0xdc}, /* qcode:Q_KEY_CODE_META_R (meta_r) -> linux:126 (KEY_RIGHTMETA) -> qnum:220 */
|
||||
{Q_KEY_CODE_MINUS, 0xc}, /* qcode:Q_KEY_CODE_MINUS (minus) -> linux:12 (KEY_MINUS) -> qnum:12 */
|
||||
{Q_KEY_CODE_MUHENKAN, 0x7b}, /* qcode:Q_KEY_CODE_MUHENKAN (muhenkan) -> linux:94 (KEY_MUHENKAN) -> qnum:123 */
|
||||
{Q_KEY_CODE_N, 0x31}, /* qcode:Q_KEY_CODE_N (n) -> linux:49 (KEY_N) -> qnum:49 */
|
||||
{Q_KEY_CODE_NUM_LOCK, 0x45}, /* qcode:Q_KEY_CODE_NUM_LOCK (num_lock) -> linux:69 (KEY_NUMLOCK) -> qnum:69 */
|
||||
{Q_KEY_CODE_O, 0x18}, /* qcode:Q_KEY_CODE_O (o) -> linux:24 (KEY_O) -> qnum:24 */
|
||||
{Q_KEY_CODE_OPEN, 0x64}, /* qcode:Q_KEY_CODE_OPEN (open) -> linux:134 (KEY_OPEN) -> qnum:100 */
|
||||
{Q_KEY_CODE_P, 0x19}, /* qcode:Q_KEY_CODE_P (p) -> linux:25 (KEY_P) -> qnum:25 */
|
||||
{Q_KEY_CODE_PASTE, 0x65}, /* qcode:Q_KEY_CODE_PASTE (paste) -> linux:135 (KEY_PASTE) -> qnum:101 */
|
||||
{Q_KEY_CODE_PAUSE, 0xc6}, /* qcode:Q_KEY_CODE_PAUSE (pause) -> linux:119 (KEY_PAUSE) -> qnum:198 */
|
||||
{Q_KEY_CODE_PGDN, 0xd1}, /* qcode:Q_KEY_CODE_PGDN (pgdn) -> linux:109 (KEY_PAGEDOWN) -> qnum:209 */
|
||||
{Q_KEY_CODE_PGUP, 0xc9}, /* qcode:Q_KEY_CODE_PGUP (pgup) -> linux:104 (KEY_PAGEUP) -> qnum:201 */
|
||||
{Q_KEY_CODE_POWER, 0xde}, /* qcode:Q_KEY_CODE_POWER (power) -> linux:116 (KEY_POWER) -> qnum:222 */
|
||||
{Q_KEY_CODE_PRINT, 0x54}, /* qcode:Q_KEY_CODE_PRINT (sysrq) -> linux:99 (KEY_SYSRQ) -> qnum:84 */
|
||||
{Q_KEY_CODE_PROPS, 0x86}, /* qcode:Q_KEY_CODE_PROPS (props) -> linux:130 (KEY_PROPS) -> qnum:134 */
|
||||
{Q_KEY_CODE_Q, 0x10}, /* qcode:Q_KEY_CODE_Q (q) -> linux:16 (KEY_Q) -> qnum:16 */
|
||||
{Q_KEY_CODE_R, 0x13}, /* qcode:Q_KEY_CODE_R (r) -> linux:19 (KEY_R) -> qnum:19 */
|
||||
{Q_KEY_CODE_RET, 0x1c}, /* qcode:Q_KEY_CODE_RET (ret) -> linux:28 (KEY_ENTER) -> qnum:28 */
|
||||
{Q_KEY_CODE_RIGHT, 0xcd}, /* qcode:Q_KEY_CODE_RIGHT (right) -> linux:106 (KEY_RIGHT) -> qnum:205 */
|
||||
{Q_KEY_CODE_RO, 0x73}, /* qcode:Q_KEY_CODE_RO (ro) -> linux:89 (KEY_RO) -> qnum:115 */
|
||||
{Q_KEY_CODE_S, 0x1f}, /* qcode:Q_KEY_CODE_S (s) -> linux:31 (KEY_S) -> qnum:31 */
|
||||
{Q_KEY_CODE_SCROLL_LOCK, 0x46}, /* qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) -> linux:70 (KEY_SCROLLLOCK) -> qnum:70 */
|
||||
{Q_KEY_CODE_SEMICOLON, 0x27}, /* qcode:Q_KEY_CODE_SEMICOLON (semicolon) -> linux:39 (KEY_SEMICOLON) -> qnum:39 */
|
||||
{Q_KEY_CODE_SHIFT, 0x2a}, /* qcode:Q_KEY_CODE_SHIFT (shift) -> linux:42 (KEY_LEFTSHIFT) -> qnum:42 */
|
||||
{Q_KEY_CODE_SHIFT_R, 0x36}, /* qcode:Q_KEY_CODE_SHIFT_R (shift_r) -> linux:54 (KEY_RIGHTSHIFT) -> qnum:54 */
|
||||
{Q_KEY_CODE_SLASH, 0x35}, /* qcode:Q_KEY_CODE_SLASH (slash) -> linux:53 (KEY_SLASH) -> qnum:53 */
|
||||
{Q_KEY_CODE_SLEEP, 0xdf}, /* qcode:Q_KEY_CODE_SLEEP (sleep) -> linux:142 (KEY_SLEEP) -> qnum:223 */
|
||||
{Q_KEY_CODE_SPC, 0x39}, /* qcode:Q_KEY_CODE_SPC (spc) -> linux:57 (KEY_SPACE) -> qnum:57 */
|
||||
{Q_KEY_CODE_STOP, 0xe8}, /* qcode:Q_KEY_CODE_STOP (stop) -> linux:128 (KEY_STOP) -> qnum:232 */
|
||||
{Q_KEY_CODE_SYSRQ, 0x54}, /* qcode:Q_KEY_CODE_SYSRQ (sysrq) -> linux:99 (KEY_SYSRQ) -> qnum:84 */
|
||||
{Q_KEY_CODE_T, 0x14}, /* qcode:Q_KEY_CODE_T (t) -> linux:20 (KEY_T) -> qnum:20 */
|
||||
{Q_KEY_CODE_TAB, 0xf}, /* qcode:Q_KEY_CODE_TAB (tab) -> linux:15 (KEY_TAB) -> qnum:15 */
|
||||
{Q_KEY_CODE_U, 0x16}, /* qcode:Q_KEY_CODE_U (u) -> linux:22 (KEY_U) -> qnum:22 */
|
||||
{Q_KEY_CODE_UNDO, 0x87}, /* qcode:Q_KEY_CODE_UNDO (undo) -> linux:131 (KEY_UNDO) -> qnum:135 */
|
||||
{Q_KEY_CODE_UP, 0xc8}, /* qcode:Q_KEY_CODE_UP (up) -> linux:103 (KEY_UP) -> qnum:200 */
|
||||
{Q_KEY_CODE_V, 0x2f}, /* qcode:Q_KEY_CODE_V (v) -> linux:47 (KEY_V) -> qnum:47 */
|
||||
{Q_KEY_CODE_VOLUMEDOWN, 0xae}, /* qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) -> linux:114 (KEY_VOLUMEDOWN) -> qnum:174 */
|
||||
{Q_KEY_CODE_VOLUMEUP, 0xb0}, /* qcode:Q_KEY_CODE_VOLUMEUP (volumeup) -> linux:115 (KEY_VOLUMEUP) -> qnum:176 */
|
||||
{Q_KEY_CODE_W, 0x11}, /* qcode:Q_KEY_CODE_W (w) -> linux:17 (KEY_W) -> qnum:17 */
|
||||
{Q_KEY_CODE_WAKE, 0xe3}, /* qcode:Q_KEY_CODE_WAKE (wake) -> linux:143 (KEY_WAKEUP) -> qnum:227 */
|
||||
{Q_KEY_CODE_X, 0x2d}, /* qcode:Q_KEY_CODE_X (x) -> linux:45 (KEY_X) -> qnum:45 */
|
||||
{Q_KEY_CODE_Y, 0x15}, /* qcode:Q_KEY_CODE_Y (y) -> linux:21 (KEY_Y) -> qnum:21 */
|
||||
{Q_KEY_CODE_YEN, 0x7d}, /* qcode:Q_KEY_CODE_YEN (yen) -> linux:124 (KEY_YEN) -> qnum:125 */
|
||||
{Q_KEY_CODE_Z, 0x2c}, /* qcode:Q_KEY_CODE_Z (z) -> linux:44 (KEY_Z) -> qnum:44 */
|
||||
};
|
||||
|
||||
int qemu_input_qcode_to_number(const QKeyCode value)
|
||||
{
|
||||
auto it = qemu_input_map_qcode_to_qnum.find(value);
|
||||
if (it == qemu_input_map_qcode_to_qnum.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
auto it = qemu_input_map_qcode_to_qnum.find(value);
|
||||
if (it == qemu_input_map_qcode_to_qnum.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int qemu_input_key_value_to_number(const KeyValue *value)
|
||||
int qemu_input_key_value_to_number(const KeyValue* value)
|
||||
{
|
||||
if (value->type == KEY_VALUE_KIND_QCODE) {
|
||||
return qemu_input_qcode_to_number(value->u.qcode);
|
||||
}
|
||||
else {
|
||||
assert(value->type == KEY_VALUE_KIND_NUMBER);
|
||||
return value->u.number;
|
||||
}
|
||||
if (value->type == KEY_VALUE_KIND_QCODE)
|
||||
{
|
||||
return qemu_input_qcode_to_number(value->u.qcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(value->type == KEY_VALUE_KIND_NUMBER);
|
||||
return value->u.number;
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
|
||||
int *codes)
|
||||
int qemu_input_key_value_to_scancode(const KeyValue* value, bool down,
|
||||
int* codes)
|
||||
{
|
||||
int keycode = qemu_input_key_value_to_number(value);
|
||||
int count = 0;
|
||||
int keycode = qemu_input_key_value_to_number(value);
|
||||
int count = 0;
|
||||
|
||||
if (value->type == KEY_VALUE_KIND_QCODE &&
|
||||
value->u.qcode == Q_KEY_CODE_PAUSE) {
|
||||
/* specific case */
|
||||
int v = down ? 0 : 0x80;
|
||||
codes[count++] = 0xe1;
|
||||
codes[count++] = 0x1d | v;
|
||||
codes[count++] = 0x45 | v;
|
||||
return count;
|
||||
}
|
||||
if (keycode & SCANCODE_GREY) {
|
||||
codes[count++] = SCANCODE_EMUL0;
|
||||
keycode &= ~SCANCODE_GREY;
|
||||
}
|
||||
if (!down) {
|
||||
keycode |= SCANCODE_UP;
|
||||
}
|
||||
codes[count++] = keycode;
|
||||
if (value->type == KEY_VALUE_KIND_QCODE &&
|
||||
value->u.qcode == Q_KEY_CODE_PAUSE)
|
||||
{
|
||||
/* specific case */
|
||||
int v = down ? 0 : 0x80;
|
||||
codes[count++] = 0xe1;
|
||||
codes[count++] = 0x1d | v;
|
||||
codes[count++] = 0x45 | v;
|
||||
return count;
|
||||
}
|
||||
if (keycode & SCANCODE_GREY)
|
||||
{
|
||||
codes[count++] = SCANCODE_EMUL0;
|
||||
keycode &= ~SCANCODE_GREY;
|
||||
}
|
||||
if (!down)
|
||||
{
|
||||
keycode |= SCANCODE_UP;
|
||||
}
|
||||
codes[count++] = keycode;
|
||||
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -20,256 +20,256 @@
|
|||
*/
|
||||
#include "input-keymap-win32-to-qcode.h"
|
||||
const std::array<QKeyCode, 252> qemu_input_map_win32_to_qcode = {
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:0 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:1 (VK_LBUTTON) -> linux:256 (BTN_0) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:2 (VK_RBUTTON) -> linux:257 (BTN_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:3 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:4 (VK_MBUTTON) -> linux:258 (BTN_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:5 (VK_XBUTTON1) -> linux:259 (BTN_3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:6 (VK_XBUTTON2) -> linux:260 (BTN_4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:7 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_BACKSPACE, /* win32:8 (VK_BACK) -> linux:14 (KEY_BACKSPACE) -> qcode:Q_KEY_CODE_BACKSPACE (backspace) */
|
||||
Q_KEY_CODE_TAB, /* win32:9 (VK_TAB) -> linux:15 (KEY_TAB) -> qcode:Q_KEY_CODE_TAB (tab) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:10 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:11 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:12 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_RET, /* win32:13 (VK_RETURN) -> linux:28 (KEY_ENTER) -> qcode:Q_KEY_CODE_RET (ret) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:14 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:15 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SHIFT, /* win32:16 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
|
||||
Q_KEY_CODE_CTRL, /* win32:17 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
|
||||
Q_KEY_CODE_ALT, /* win32:18 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
|
||||
Q_KEY_CODE_PAUSE, /* win32:19 (VK_PAUSE) -> linux:119 (KEY_PAUSE) -> qcode:Q_KEY_CODE_PAUSE (pause) */
|
||||
Q_KEY_CODE_CAPS_LOCK, /* win32:20 (VK_CAPITAL) -> linux:58 (KEY_CAPSLOCK) -> qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:21 (VK_HANGEUL) -> linux:122 (KEY_HANGEUL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:22 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:23 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:24 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:25 (VK_HANJA) -> linux:123 (KEY_HANJA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:26 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_ESC, /* win32:27 (VK_ESCAPE) -> linux:1 (KEY_ESC) -> qcode:Q_KEY_CODE_ESC (esc) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:28 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:29 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:30 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:31 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SPC, /* win32:32 (VK_SPACE) -> linux:57 (KEY_SPACE) -> qcode:Q_KEY_CODE_SPC (spc) */
|
||||
Q_KEY_CODE_PGUP, /* win32:33 (VK_PRIOR) -> linux:104 (KEY_PAGEUP) -> qcode:Q_KEY_CODE_PGUP (pgup) */
|
||||
Q_KEY_CODE_PGDN, /* win32:34 (VK_NEXT) -> linux:109 (KEY_PAGEDOWN) -> qcode:Q_KEY_CODE_PGDN (pgdn) */
|
||||
Q_KEY_CODE_END, /* win32:35 (VK_END) -> linux:107 (KEY_END) -> qcode:Q_KEY_CODE_END (end) */
|
||||
Q_KEY_CODE_HOME, /* win32:36 (VK_HOME) -> linux:102 (KEY_HOME) -> qcode:Q_KEY_CODE_HOME (home) */
|
||||
Q_KEY_CODE_LEFT, /* win32:37 (VK_LEFT) -> linux:105 (KEY_LEFT) -> qcode:Q_KEY_CODE_LEFT (left) */
|
||||
Q_KEY_CODE_UP, /* win32:38 (VK_UP) -> linux:103 (KEY_UP) -> qcode:Q_KEY_CODE_UP (up) */
|
||||
Q_KEY_CODE_RIGHT, /* win32:39 (VK_RIGHT) -> linux:106 (KEY_RIGHT) -> qcode:Q_KEY_CODE_RIGHT (right) */
|
||||
Q_KEY_CODE_DOWN, /* win32:40 (VK_DOWN) -> linux:108 (KEY_DOWN) -> qcode:Q_KEY_CODE_DOWN (down) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:41 (VK_SELECT) -> linux:353 (KEY_SELECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:42 (VK_PRINT) -> linux:210 (KEY_PRINT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:43 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SYSRQ, /* win32:44 (VK_SNAPSHOT) -> linux:99 (KEY_SYSRQ) -> qcode:Q_KEY_CODE_SYSRQ (sysrq) */
|
||||
Q_KEY_CODE_INSERT, /* win32:45 (VK_INSERT) -> linux:110 (KEY_INSERT) -> qcode:Q_KEY_CODE_INSERT (insert) */
|
||||
Q_KEY_CODE_DELETE, /* win32:46 (VK_DELETE) -> linux:111 (KEY_DELETE) -> qcode:Q_KEY_CODE_DELETE (delete) */
|
||||
Q_KEY_CODE_HELP, /* win32:47 (VK_HELP) -> linux:138 (KEY_HELP) -> qcode:Q_KEY_CODE_HELP (help) */
|
||||
Q_KEY_CODE_0, /* win32:48 (VK_0) -> linux:11 (KEY_0) -> qcode:Q_KEY_CODE_0 (0) */
|
||||
Q_KEY_CODE_1, /* win32:49 (VK_1) -> linux:2 (KEY_1) -> qcode:Q_KEY_CODE_1 (1) */
|
||||
Q_KEY_CODE_2, /* win32:50 (VK_2) -> linux:3 (KEY_2) -> qcode:Q_KEY_CODE_2 (2) */
|
||||
Q_KEY_CODE_3, /* win32:51 (VK_3) -> linux:4 (KEY_3) -> qcode:Q_KEY_CODE_3 (3) */
|
||||
Q_KEY_CODE_4, /* win32:52 (VK_4) -> linux:5 (KEY_4) -> qcode:Q_KEY_CODE_4 (4) */
|
||||
Q_KEY_CODE_5, /* win32:53 (VK_5) -> linux:6 (KEY_5) -> qcode:Q_KEY_CODE_5 (5) */
|
||||
Q_KEY_CODE_6, /* win32:54 (VK_6) -> linux:7 (KEY_6) -> qcode:Q_KEY_CODE_6 (6) */
|
||||
Q_KEY_CODE_7, /* win32:55 (VK_7) -> linux:8 (KEY_7) -> qcode:Q_KEY_CODE_7 (7) */
|
||||
Q_KEY_CODE_8, /* win32:56 (VK_8) -> linux:9 (KEY_8) -> qcode:Q_KEY_CODE_8 (8) */
|
||||
Q_KEY_CODE_9, /* win32:57 (VK_9) -> linux:10 (KEY_9) -> qcode:Q_KEY_CODE_9 (9) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:58 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:59 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:60 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:61 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:62 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:63 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:64 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_A, /* win32:65 (VK_A) -> linux:30 (KEY_A) -> qcode:Q_KEY_CODE_A (a) */
|
||||
Q_KEY_CODE_B, /* win32:66 (VK_B) -> linux:48 (KEY_B) -> qcode:Q_KEY_CODE_B (b) */
|
||||
Q_KEY_CODE_C, /* win32:67 (VK_C) -> linux:46 (KEY_C) -> qcode:Q_KEY_CODE_C (c) */
|
||||
Q_KEY_CODE_D, /* win32:68 (VK_D) -> linux:32 (KEY_D) -> qcode:Q_KEY_CODE_D (d) */
|
||||
Q_KEY_CODE_E, /* win32:69 (VK_E) -> linux:18 (KEY_E) -> qcode:Q_KEY_CODE_E (e) */
|
||||
Q_KEY_CODE_F, /* win32:70 (VK_F) -> linux:33 (KEY_F) -> qcode:Q_KEY_CODE_F (f) */
|
||||
Q_KEY_CODE_G, /* win32:71 (VK_G) -> linux:34 (KEY_G) -> qcode:Q_KEY_CODE_G (g) */
|
||||
Q_KEY_CODE_H, /* win32:72 (VK_H) -> linux:35 (KEY_H) -> qcode:Q_KEY_CODE_H (h) */
|
||||
Q_KEY_CODE_I, /* win32:73 (VK_I) -> linux:23 (KEY_I) -> qcode:Q_KEY_CODE_I (i) */
|
||||
Q_KEY_CODE_J, /* win32:74 (VK_J) -> linux:36 (KEY_J) -> qcode:Q_KEY_CODE_J (j) */
|
||||
Q_KEY_CODE_K, /* win32:75 (VK_K) -> linux:37 (KEY_K) -> qcode:Q_KEY_CODE_K (k) */
|
||||
Q_KEY_CODE_L, /* win32:76 (VK_L) -> linux:38 (KEY_L) -> qcode:Q_KEY_CODE_L (l) */
|
||||
Q_KEY_CODE_M, /* win32:77 (VK_M) -> linux:50 (KEY_M) -> qcode:Q_KEY_CODE_M (m) */
|
||||
Q_KEY_CODE_N, /* win32:78 (VK_N) -> linux:49 (KEY_N) -> qcode:Q_KEY_CODE_N (n) */
|
||||
Q_KEY_CODE_O, /* win32:79 (VK_O) -> linux:24 (KEY_O) -> qcode:Q_KEY_CODE_O (o) */
|
||||
Q_KEY_CODE_P, /* win32:80 (VK_P) -> linux:25 (KEY_P) -> qcode:Q_KEY_CODE_P (p) */
|
||||
Q_KEY_CODE_Q, /* win32:81 (VK_Q) -> linux:16 (KEY_Q) -> qcode:Q_KEY_CODE_Q (q) */
|
||||
Q_KEY_CODE_R, /* win32:82 (VK_R) -> linux:19 (KEY_R) -> qcode:Q_KEY_CODE_R (r) */
|
||||
Q_KEY_CODE_S, /* win32:83 (VK_S) -> linux:31 (KEY_S) -> qcode:Q_KEY_CODE_S (s) */
|
||||
Q_KEY_CODE_T, /* win32:84 (VK_T) -> linux:20 (KEY_T) -> qcode:Q_KEY_CODE_T (t) */
|
||||
Q_KEY_CODE_U, /* win32:85 (VK_U) -> linux:22 (KEY_U) -> qcode:Q_KEY_CODE_U (u) */
|
||||
Q_KEY_CODE_V, /* win32:86 (VK_V) -> linux:47 (KEY_V) -> qcode:Q_KEY_CODE_V (v) */
|
||||
Q_KEY_CODE_W, /* win32:87 (VK_W) -> linux:17 (KEY_W) -> qcode:Q_KEY_CODE_W (w) */
|
||||
Q_KEY_CODE_X, /* win32:88 (VK_X) -> linux:45 (KEY_X) -> qcode:Q_KEY_CODE_X (x) */
|
||||
Q_KEY_CODE_Y, /* win32:89 (VK_Y) -> linux:21 (KEY_Y) -> qcode:Q_KEY_CODE_Y (y) */
|
||||
Q_KEY_CODE_Z, /* win32:90 (VK_Z) -> linux:44 (KEY_Z) -> qcode:Q_KEY_CODE_Z (z) */
|
||||
Q_KEY_CODE_META_L, /* win32:91 (VK_LWIN) -> linux:125 (KEY_LEFTMETA) -> qcode:Q_KEY_CODE_META_L (meta_l) */
|
||||
Q_KEY_CODE_META_R, /* win32:92 (VK_RWIN) -> linux:126 (KEY_RIGHTMETA) -> qcode:Q_KEY_CODE_META_R (meta_r) */
|
||||
Q_KEY_CODE_COMPOSE, /* win32:93 (VK_APPS) -> linux:127 (KEY_COMPOSE) -> qcode:Q_KEY_CODE_COMPOSE (compose) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:94 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SLEEP, /* win32:95 (VK_SLEEP) -> linux:142 (KEY_SLEEP) -> qcode:Q_KEY_CODE_SLEEP (sleep) */
|
||||
Q_KEY_CODE_KP_0, /* win32:96 (VK_NUMPAD0) -> linux:82 (KEY_KP0) -> qcode:Q_KEY_CODE_KP_0 (kp_0) */
|
||||
Q_KEY_CODE_KP_1, /* win32:97 (VK_NUMPAD1) -> linux:79 (KEY_KP1) -> qcode:Q_KEY_CODE_KP_1 (kp_1) */
|
||||
Q_KEY_CODE_KP_2, /* win32:98 (VK_NUMPAD2) -> linux:80 (KEY_KP2) -> qcode:Q_KEY_CODE_KP_2 (kp_2) */
|
||||
Q_KEY_CODE_KP_3, /* win32:99 (VK_NUMPAD3) -> linux:81 (KEY_KP3) -> qcode:Q_KEY_CODE_KP_3 (kp_3) */
|
||||
Q_KEY_CODE_KP_4, /* win32:100 (VK_NUMPAD4) -> linux:75 (KEY_KP4) -> qcode:Q_KEY_CODE_KP_4 (kp_4) */
|
||||
Q_KEY_CODE_KP_5, /* win32:101 (VK_NUMPAD5) -> linux:76 (KEY_KP5) -> qcode:Q_KEY_CODE_KP_5 (kp_5) */
|
||||
Q_KEY_CODE_KP_6, /* win32:102 (VK_NUMPAD6) -> linux:77 (KEY_KP6) -> qcode:Q_KEY_CODE_KP_6 (kp_6) */
|
||||
Q_KEY_CODE_KP_7, /* win32:103 (VK_NUMPAD7) -> linux:71 (KEY_KP7) -> qcode:Q_KEY_CODE_KP_7 (kp_7) */
|
||||
Q_KEY_CODE_KP_8, /* win32:104 (VK_NUMPAD8) -> linux:72 (KEY_KP8) -> qcode:Q_KEY_CODE_KP_8 (kp_8) */
|
||||
Q_KEY_CODE_KP_9, /* win32:105 (VK_NUMPAD9) -> linux:73 (KEY_KP9) -> qcode:Q_KEY_CODE_KP_9 (kp_9) */
|
||||
Q_KEY_CODE_KP_MULTIPLY, /* win32:106 (VK_MULTIPLY) -> linux:55 (KEY_KPASTERISK) -> qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) */
|
||||
Q_KEY_CODE_KP_ADD, /* win32:107 (VK_ADD) -> linux:78 (KEY_KPPLUS) -> qcode:Q_KEY_CODE_KP_ADD (kp_add) */
|
||||
Q_KEY_CODE_KP_COMMA, /* win32:108 (VK_SEPARATOR??) -> linux:121 (KEY_KPCOMMA) -> qcode:Q_KEY_CODE_KP_COMMA (kp_comma) */
|
||||
Q_KEY_CODE_KP_SUBTRACT, /* win32:109 (VK_SUBTRACT) -> linux:74 (KEY_KPMINUS) -> qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) */
|
||||
Q_KEY_CODE_KP_DECIMAL, /* win32:110 (VK_DECIMAL) -> linux:83 (KEY_KPDOT) -> qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) */
|
||||
Q_KEY_CODE_KP_DIVIDE, /* win32:111 (VK_DIVIDE) -> linux:98 (KEY_KPSLASH) -> qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) */
|
||||
Q_KEY_CODE_F1, /* win32:112 (VK_F1) -> linux:59 (KEY_F1) -> qcode:Q_KEY_CODE_F1 (f1) */
|
||||
Q_KEY_CODE_F2, /* win32:113 (VK_F2) -> linux:60 (KEY_F2) -> qcode:Q_KEY_CODE_F2 (f2) */
|
||||
Q_KEY_CODE_F3, /* win32:114 (VK_F3) -> linux:61 (KEY_F3) -> qcode:Q_KEY_CODE_F3 (f3) */
|
||||
Q_KEY_CODE_F4, /* win32:115 (VK_F4) -> linux:62 (KEY_F4) -> qcode:Q_KEY_CODE_F4 (f4) */
|
||||
Q_KEY_CODE_F5, /* win32:116 (VK_F5) -> linux:63 (KEY_F5) -> qcode:Q_KEY_CODE_F5 (f5) */
|
||||
Q_KEY_CODE_F6, /* win32:117 (VK_F6) -> linux:64 (KEY_F6) -> qcode:Q_KEY_CODE_F6 (f6) */
|
||||
Q_KEY_CODE_F7, /* win32:118 (VK_F7) -> linux:65 (KEY_F7) -> qcode:Q_KEY_CODE_F7 (f7) */
|
||||
Q_KEY_CODE_F8, /* win32:119 (VK_F8) -> linux:66 (KEY_F8) -> qcode:Q_KEY_CODE_F8 (f8) */
|
||||
Q_KEY_CODE_F9, /* win32:120 (VK_F9) -> linux:67 (KEY_F9) -> qcode:Q_KEY_CODE_F9 (f9) */
|
||||
Q_KEY_CODE_F10, /* win32:121 (VK_F10) -> linux:68 (KEY_F10) -> qcode:Q_KEY_CODE_F10 (f10) */
|
||||
Q_KEY_CODE_F11, /* win32:122 (VK_F11) -> linux:87 (KEY_F11) -> qcode:Q_KEY_CODE_F11 (f11) */
|
||||
Q_KEY_CODE_F12, /* win32:123 (VK_F12) -> linux:88 (KEY_F12) -> qcode:Q_KEY_CODE_F12 (f12) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:124 (VK_F13) -> linux:183 (KEY_F13) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:125 (VK_F14) -> linux:184 (KEY_F14) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:126 (VK_F15) -> linux:185 (KEY_F15) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:127 (VK_F16) -> linux:186 (KEY_F16) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:128 (VK_F17) -> linux:187 (KEY_F17) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:129 (VK_F18) -> linux:188 (KEY_F18) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:130 (VK_F19) -> linux:189 (KEY_F19) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:131 (VK_F20) -> linux:190 (KEY_F20) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:132 (VK_F21) -> linux:191 (KEY_F21) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:133 (VK_F22) -> linux:192 (KEY_F22) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:134 (VK_F23) -> linux:193 (KEY_F23) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:135 (VK_F24) -> linux:194 (KEY_F24) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:136 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:137 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:138 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:139 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:140 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:141 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:142 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:143 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_NUM_LOCK, /* win32:144 (VK_NUMLOCK) -> linux:69 (KEY_NUMLOCK) -> qcode:Q_KEY_CODE_NUM_LOCK (num_lock) */
|
||||
Q_KEY_CODE_SCROLL_LOCK, /* win32:145 (VK_SCROLL) -> linux:70 (KEY_SCROLLLOCK) -> qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:146 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:147 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:148 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:149 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:150 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:151 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:152 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:153 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:154 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:155 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:156 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:157 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:158 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:159 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SHIFT, /* win32:160 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
|
||||
Q_KEY_CODE_SHIFT_R, /* win32:161 (VK_RSHIFT) -> linux:54 (KEY_RIGHTSHIFT) -> qcode:Q_KEY_CODE_SHIFT_R (shift_r) */
|
||||
Q_KEY_CODE_CTRL, /* win32:162 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
|
||||
Q_KEY_CODE_CTRL_R, /* win32:163 (VK_RCONTROL) -> linux:97 (KEY_RIGHTCTRL) -> qcode:Q_KEY_CODE_CTRL_R (ctrl_r) */
|
||||
Q_KEY_CODE_ALT, /* win32:164 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
|
||||
Q_KEY_CODE_ALT_R, /* win32:165 (VK_RMENU) -> linux:100 (KEY_RIGHTALT) -> qcode:Q_KEY_CODE_ALT_R (alt_r) */
|
||||
Q_KEY_CODE_AC_BACK, /* win32:166 (VK_BROWSER_BACK) -> linux:158 (KEY_BACK) -> qcode:Q_KEY_CODE_AC_BACK (ac_back) */
|
||||
Q_KEY_CODE_AC_FORWARD, /* win32:167 (VK_BROWSER_FORWARD) -> linux:159 (KEY_FORWARD) -> qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) */
|
||||
Q_KEY_CODE_AC_REFRESH, /* win32:168 (VK_BROWSER_REFRESH) -> linux:173 (KEY_REFRESH) -> qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) */
|
||||
Q_KEY_CODE_STOP, /* win32:169 (VK_BROWSER_STOP) -> linux:128 (KEY_STOP) -> qcode:Q_KEY_CODE_STOP (stop) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:170 (VK_BROWSER_SEARCH) -> linux:217 (KEY_SEARCH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:171 (VK_BROWSER_FAVOURITES) -> linux:364 (KEY_FAVORITES) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_AC_HOME, /* win32:172 (VK_BROWSER_HOME) -> linux:172 (KEY_HOMEPAGE) -> qcode:Q_KEY_CODE_AC_HOME (ac_home) */
|
||||
Q_KEY_CODE_AUDIOMUTE, /* win32:173 (VK_VOLUME_MUTE) -> linux:113 (KEY_MUTE) -> qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) */
|
||||
Q_KEY_CODE_VOLUMEDOWN, /* win32:174 (VK_VOLUME_DOWN) -> linux:114 (KEY_VOLUMEDOWN) -> qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) */
|
||||
Q_KEY_CODE_VOLUMEUP, /* win32:175 (VK_VOLUME_UP) -> linux:115 (KEY_VOLUMEUP) -> qcode:Q_KEY_CODE_VOLUMEUP (volumeup) */
|
||||
Q_KEY_CODE_AUDIONEXT, /* win32:176 (VK_MEDIA_NEXT_TRACK) -> linux:163 (KEY_NEXTSONG) -> qcode:Q_KEY_CODE_AUDIONEXT (audionext) */
|
||||
Q_KEY_CODE_AUDIOPREV, /* win32:177 (VK_MEDIA_PREV_TRACK) -> linux:165 (KEY_PREVIOUSSONG) -> qcode:Q_KEY_CODE_AUDIOPREV (audioprev) */
|
||||
Q_KEY_CODE_AUDIOSTOP, /* win32:178 (VK_MEDIA_STOP) -> linux:166 (KEY_STOPCD) -> qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) */
|
||||
Q_KEY_CODE_AUDIOPLAY, /* win32:179 (VK_MEDIA_PLAY_PAUSE) -> linux:164 (KEY_PLAYPAUSE) -> qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:180 (VK_LAUNCH_MAIL) -> linux:215 (KEY_EMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:181 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:182 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:183 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:184 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:185 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SEMICOLON, /* win32:186 (VK_OEM_1) -> linux:39 (KEY_SEMICOLON) -> qcode:Q_KEY_CODE_SEMICOLON (semicolon) */
|
||||
Q_KEY_CODE_EQUAL, /* win32:187 (VK_OEM_PLUS) -> linux:13 (KEY_EQUAL) -> qcode:Q_KEY_CODE_EQUAL (equal) */
|
||||
Q_KEY_CODE_COMMA, /* win32:188 (VK_OEM_COMMA) -> linux:51 (KEY_COMMA) -> qcode:Q_KEY_CODE_COMMA (comma) */
|
||||
Q_KEY_CODE_MINUS, /* win32:189 (VK_OEM_MINUS) -> linux:12 (KEY_MINUS) -> qcode:Q_KEY_CODE_MINUS (minus) */
|
||||
Q_KEY_CODE_DOT, /* win32:190 (VK_OEM_PERIOD) -> linux:52 (KEY_DOT) -> qcode:Q_KEY_CODE_DOT (dot) */
|
||||
Q_KEY_CODE_SLASH, /* win32:191 (VK_OEM_2) -> linux:53 (KEY_SLASH) -> qcode:Q_KEY_CODE_SLASH (slash) */
|
||||
Q_KEY_CODE_GRAVE_ACCENT, /* win32:192 (VK_OEM_3) -> linux:41 (KEY_GRAVE) -> qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:193 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:194 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:195 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:196 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:197 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:198 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:199 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:200 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:201 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:202 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:203 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:204 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:205 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:206 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:207 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:208 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:209 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:210 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:211 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:212 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:213 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:214 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:215 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:216 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:217 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:218 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_BRACKET_LEFT, /* win32:219 (VK_OEM_4) -> linux:26 (KEY_LEFTBRACE) -> qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) */
|
||||
Q_KEY_CODE_BACKSLASH, /* win32:220 (VK_OEM_5) -> linux:43 (KEY_BACKSLASH) -> qcode:Q_KEY_CODE_BACKSLASH (backslash) */
|
||||
Q_KEY_CODE_BRACKET_RIGHT, /* win32:221 (VK_OEM_6) -> linux:27 (KEY_RIGHTBRACE) -> qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) */
|
||||
Q_KEY_CODE_APOSTROPHE, /* win32:222 (VK_OEM_7) -> linux:40 (KEY_APOSTROPHE) -> qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:223 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:224 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_LESS, /* win32:225 (VK_OEM_102) -> linux:86 (KEY_102ND) -> qcode:Q_KEY_CODE_LESS (less) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:226 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:227 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:228 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:229 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:230 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:231 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:232 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:233 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:234 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:235 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:236 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:237 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:238 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:239 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:240 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:241 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:242 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:243 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:244 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:245 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:246 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:247 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:248 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:249 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:250 (VK_PLAY) -> linux:207 (KEY_PLAY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:251 (VK_ZOOM) -> linux:372 (KEY_ZOOM) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:0 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:1 (VK_LBUTTON) -> linux:256 (BTN_0) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:2 (VK_RBUTTON) -> linux:257 (BTN_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:3 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:4 (VK_MBUTTON) -> linux:258 (BTN_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:5 (VK_XBUTTON1) -> linux:259 (BTN_3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:6 (VK_XBUTTON2) -> linux:260 (BTN_4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:7 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_BACKSPACE, /* win32:8 (VK_BACK) -> linux:14 (KEY_BACKSPACE) -> qcode:Q_KEY_CODE_BACKSPACE (backspace) */
|
||||
Q_KEY_CODE_TAB, /* win32:9 (VK_TAB) -> linux:15 (KEY_TAB) -> qcode:Q_KEY_CODE_TAB (tab) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:10 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:11 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:12 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_RET, /* win32:13 (VK_RETURN) -> linux:28 (KEY_ENTER) -> qcode:Q_KEY_CODE_RET (ret) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:14 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:15 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SHIFT, /* win32:16 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
|
||||
Q_KEY_CODE_CTRL, /* win32:17 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
|
||||
Q_KEY_CODE_ALT, /* win32:18 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
|
||||
Q_KEY_CODE_PAUSE, /* win32:19 (VK_PAUSE) -> linux:119 (KEY_PAUSE) -> qcode:Q_KEY_CODE_PAUSE (pause) */
|
||||
Q_KEY_CODE_CAPS_LOCK, /* win32:20 (VK_CAPITAL) -> linux:58 (KEY_CAPSLOCK) -> qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:21 (VK_HANGEUL) -> linux:122 (KEY_HANGEUL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:22 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:23 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:24 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:25 (VK_HANJA) -> linux:123 (KEY_HANJA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:26 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_ESC, /* win32:27 (VK_ESCAPE) -> linux:1 (KEY_ESC) -> qcode:Q_KEY_CODE_ESC (esc) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:28 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:29 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:30 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:31 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SPC, /* win32:32 (VK_SPACE) -> linux:57 (KEY_SPACE) -> qcode:Q_KEY_CODE_SPC (spc) */
|
||||
Q_KEY_CODE_PGUP, /* win32:33 (VK_PRIOR) -> linux:104 (KEY_PAGEUP) -> qcode:Q_KEY_CODE_PGUP (pgup) */
|
||||
Q_KEY_CODE_PGDN, /* win32:34 (VK_NEXT) -> linux:109 (KEY_PAGEDOWN) -> qcode:Q_KEY_CODE_PGDN (pgdn) */
|
||||
Q_KEY_CODE_END, /* win32:35 (VK_END) -> linux:107 (KEY_END) -> qcode:Q_KEY_CODE_END (end) */
|
||||
Q_KEY_CODE_HOME, /* win32:36 (VK_HOME) -> linux:102 (KEY_HOME) -> qcode:Q_KEY_CODE_HOME (home) */
|
||||
Q_KEY_CODE_LEFT, /* win32:37 (VK_LEFT) -> linux:105 (KEY_LEFT) -> qcode:Q_KEY_CODE_LEFT (left) */
|
||||
Q_KEY_CODE_UP, /* win32:38 (VK_UP) -> linux:103 (KEY_UP) -> qcode:Q_KEY_CODE_UP (up) */
|
||||
Q_KEY_CODE_RIGHT, /* win32:39 (VK_RIGHT) -> linux:106 (KEY_RIGHT) -> qcode:Q_KEY_CODE_RIGHT (right) */
|
||||
Q_KEY_CODE_DOWN, /* win32:40 (VK_DOWN) -> linux:108 (KEY_DOWN) -> qcode:Q_KEY_CODE_DOWN (down) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:41 (VK_SELECT) -> linux:353 (KEY_SELECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:42 (VK_PRINT) -> linux:210 (KEY_PRINT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:43 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SYSRQ, /* win32:44 (VK_SNAPSHOT) -> linux:99 (KEY_SYSRQ) -> qcode:Q_KEY_CODE_SYSRQ (sysrq) */
|
||||
Q_KEY_CODE_INSERT, /* win32:45 (VK_INSERT) -> linux:110 (KEY_INSERT) -> qcode:Q_KEY_CODE_INSERT (insert) */
|
||||
Q_KEY_CODE_DELETE, /* win32:46 (VK_DELETE) -> linux:111 (KEY_DELETE) -> qcode:Q_KEY_CODE_DELETE (delete) */
|
||||
Q_KEY_CODE_HELP, /* win32:47 (VK_HELP) -> linux:138 (KEY_HELP) -> qcode:Q_KEY_CODE_HELP (help) */
|
||||
Q_KEY_CODE_0, /* win32:48 (VK_0) -> linux:11 (KEY_0) -> qcode:Q_KEY_CODE_0 (0) */
|
||||
Q_KEY_CODE_1, /* win32:49 (VK_1) -> linux:2 (KEY_1) -> qcode:Q_KEY_CODE_1 (1) */
|
||||
Q_KEY_CODE_2, /* win32:50 (VK_2) -> linux:3 (KEY_2) -> qcode:Q_KEY_CODE_2 (2) */
|
||||
Q_KEY_CODE_3, /* win32:51 (VK_3) -> linux:4 (KEY_3) -> qcode:Q_KEY_CODE_3 (3) */
|
||||
Q_KEY_CODE_4, /* win32:52 (VK_4) -> linux:5 (KEY_4) -> qcode:Q_KEY_CODE_4 (4) */
|
||||
Q_KEY_CODE_5, /* win32:53 (VK_5) -> linux:6 (KEY_5) -> qcode:Q_KEY_CODE_5 (5) */
|
||||
Q_KEY_CODE_6, /* win32:54 (VK_6) -> linux:7 (KEY_6) -> qcode:Q_KEY_CODE_6 (6) */
|
||||
Q_KEY_CODE_7, /* win32:55 (VK_7) -> linux:8 (KEY_7) -> qcode:Q_KEY_CODE_7 (7) */
|
||||
Q_KEY_CODE_8, /* win32:56 (VK_8) -> linux:9 (KEY_8) -> qcode:Q_KEY_CODE_8 (8) */
|
||||
Q_KEY_CODE_9, /* win32:57 (VK_9) -> linux:10 (KEY_9) -> qcode:Q_KEY_CODE_9 (9) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:58 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:59 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:60 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:61 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:62 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:63 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:64 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_A, /* win32:65 (VK_A) -> linux:30 (KEY_A) -> qcode:Q_KEY_CODE_A (a) */
|
||||
Q_KEY_CODE_B, /* win32:66 (VK_B) -> linux:48 (KEY_B) -> qcode:Q_KEY_CODE_B (b) */
|
||||
Q_KEY_CODE_C, /* win32:67 (VK_C) -> linux:46 (KEY_C) -> qcode:Q_KEY_CODE_C (c) */
|
||||
Q_KEY_CODE_D, /* win32:68 (VK_D) -> linux:32 (KEY_D) -> qcode:Q_KEY_CODE_D (d) */
|
||||
Q_KEY_CODE_E, /* win32:69 (VK_E) -> linux:18 (KEY_E) -> qcode:Q_KEY_CODE_E (e) */
|
||||
Q_KEY_CODE_F, /* win32:70 (VK_F) -> linux:33 (KEY_F) -> qcode:Q_KEY_CODE_F (f) */
|
||||
Q_KEY_CODE_G, /* win32:71 (VK_G) -> linux:34 (KEY_G) -> qcode:Q_KEY_CODE_G (g) */
|
||||
Q_KEY_CODE_H, /* win32:72 (VK_H) -> linux:35 (KEY_H) -> qcode:Q_KEY_CODE_H (h) */
|
||||
Q_KEY_CODE_I, /* win32:73 (VK_I) -> linux:23 (KEY_I) -> qcode:Q_KEY_CODE_I (i) */
|
||||
Q_KEY_CODE_J, /* win32:74 (VK_J) -> linux:36 (KEY_J) -> qcode:Q_KEY_CODE_J (j) */
|
||||
Q_KEY_CODE_K, /* win32:75 (VK_K) -> linux:37 (KEY_K) -> qcode:Q_KEY_CODE_K (k) */
|
||||
Q_KEY_CODE_L, /* win32:76 (VK_L) -> linux:38 (KEY_L) -> qcode:Q_KEY_CODE_L (l) */
|
||||
Q_KEY_CODE_M, /* win32:77 (VK_M) -> linux:50 (KEY_M) -> qcode:Q_KEY_CODE_M (m) */
|
||||
Q_KEY_CODE_N, /* win32:78 (VK_N) -> linux:49 (KEY_N) -> qcode:Q_KEY_CODE_N (n) */
|
||||
Q_KEY_CODE_O, /* win32:79 (VK_O) -> linux:24 (KEY_O) -> qcode:Q_KEY_CODE_O (o) */
|
||||
Q_KEY_CODE_P, /* win32:80 (VK_P) -> linux:25 (KEY_P) -> qcode:Q_KEY_CODE_P (p) */
|
||||
Q_KEY_CODE_Q, /* win32:81 (VK_Q) -> linux:16 (KEY_Q) -> qcode:Q_KEY_CODE_Q (q) */
|
||||
Q_KEY_CODE_R, /* win32:82 (VK_R) -> linux:19 (KEY_R) -> qcode:Q_KEY_CODE_R (r) */
|
||||
Q_KEY_CODE_S, /* win32:83 (VK_S) -> linux:31 (KEY_S) -> qcode:Q_KEY_CODE_S (s) */
|
||||
Q_KEY_CODE_T, /* win32:84 (VK_T) -> linux:20 (KEY_T) -> qcode:Q_KEY_CODE_T (t) */
|
||||
Q_KEY_CODE_U, /* win32:85 (VK_U) -> linux:22 (KEY_U) -> qcode:Q_KEY_CODE_U (u) */
|
||||
Q_KEY_CODE_V, /* win32:86 (VK_V) -> linux:47 (KEY_V) -> qcode:Q_KEY_CODE_V (v) */
|
||||
Q_KEY_CODE_W, /* win32:87 (VK_W) -> linux:17 (KEY_W) -> qcode:Q_KEY_CODE_W (w) */
|
||||
Q_KEY_CODE_X, /* win32:88 (VK_X) -> linux:45 (KEY_X) -> qcode:Q_KEY_CODE_X (x) */
|
||||
Q_KEY_CODE_Y, /* win32:89 (VK_Y) -> linux:21 (KEY_Y) -> qcode:Q_KEY_CODE_Y (y) */
|
||||
Q_KEY_CODE_Z, /* win32:90 (VK_Z) -> linux:44 (KEY_Z) -> qcode:Q_KEY_CODE_Z (z) */
|
||||
Q_KEY_CODE_META_L, /* win32:91 (VK_LWIN) -> linux:125 (KEY_LEFTMETA) -> qcode:Q_KEY_CODE_META_L (meta_l) */
|
||||
Q_KEY_CODE_META_R, /* win32:92 (VK_RWIN) -> linux:126 (KEY_RIGHTMETA) -> qcode:Q_KEY_CODE_META_R (meta_r) */
|
||||
Q_KEY_CODE_COMPOSE, /* win32:93 (VK_APPS) -> linux:127 (KEY_COMPOSE) -> qcode:Q_KEY_CODE_COMPOSE (compose) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:94 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SLEEP, /* win32:95 (VK_SLEEP) -> linux:142 (KEY_SLEEP) -> qcode:Q_KEY_CODE_SLEEP (sleep) */
|
||||
Q_KEY_CODE_KP_0, /* win32:96 (VK_NUMPAD0) -> linux:82 (KEY_KP0) -> qcode:Q_KEY_CODE_KP_0 (kp_0) */
|
||||
Q_KEY_CODE_KP_1, /* win32:97 (VK_NUMPAD1) -> linux:79 (KEY_KP1) -> qcode:Q_KEY_CODE_KP_1 (kp_1) */
|
||||
Q_KEY_CODE_KP_2, /* win32:98 (VK_NUMPAD2) -> linux:80 (KEY_KP2) -> qcode:Q_KEY_CODE_KP_2 (kp_2) */
|
||||
Q_KEY_CODE_KP_3, /* win32:99 (VK_NUMPAD3) -> linux:81 (KEY_KP3) -> qcode:Q_KEY_CODE_KP_3 (kp_3) */
|
||||
Q_KEY_CODE_KP_4, /* win32:100 (VK_NUMPAD4) -> linux:75 (KEY_KP4) -> qcode:Q_KEY_CODE_KP_4 (kp_4) */
|
||||
Q_KEY_CODE_KP_5, /* win32:101 (VK_NUMPAD5) -> linux:76 (KEY_KP5) -> qcode:Q_KEY_CODE_KP_5 (kp_5) */
|
||||
Q_KEY_CODE_KP_6, /* win32:102 (VK_NUMPAD6) -> linux:77 (KEY_KP6) -> qcode:Q_KEY_CODE_KP_6 (kp_6) */
|
||||
Q_KEY_CODE_KP_7, /* win32:103 (VK_NUMPAD7) -> linux:71 (KEY_KP7) -> qcode:Q_KEY_CODE_KP_7 (kp_7) */
|
||||
Q_KEY_CODE_KP_8, /* win32:104 (VK_NUMPAD8) -> linux:72 (KEY_KP8) -> qcode:Q_KEY_CODE_KP_8 (kp_8) */
|
||||
Q_KEY_CODE_KP_9, /* win32:105 (VK_NUMPAD9) -> linux:73 (KEY_KP9) -> qcode:Q_KEY_CODE_KP_9 (kp_9) */
|
||||
Q_KEY_CODE_KP_MULTIPLY, /* win32:106 (VK_MULTIPLY) -> linux:55 (KEY_KPASTERISK) -> qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) */
|
||||
Q_KEY_CODE_KP_ADD, /* win32:107 (VK_ADD) -> linux:78 (KEY_KPPLUS) -> qcode:Q_KEY_CODE_KP_ADD (kp_add) */
|
||||
Q_KEY_CODE_KP_COMMA, /* win32:108 (VK_SEPARATOR??) -> linux:121 (KEY_KPCOMMA) -> qcode:Q_KEY_CODE_KP_COMMA (kp_comma) */
|
||||
Q_KEY_CODE_KP_SUBTRACT, /* win32:109 (VK_SUBTRACT) -> linux:74 (KEY_KPMINUS) -> qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) */
|
||||
Q_KEY_CODE_KP_DECIMAL, /* win32:110 (VK_DECIMAL) -> linux:83 (KEY_KPDOT) -> qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) */
|
||||
Q_KEY_CODE_KP_DIVIDE, /* win32:111 (VK_DIVIDE) -> linux:98 (KEY_KPSLASH) -> qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) */
|
||||
Q_KEY_CODE_F1, /* win32:112 (VK_F1) -> linux:59 (KEY_F1) -> qcode:Q_KEY_CODE_F1 (f1) */
|
||||
Q_KEY_CODE_F2, /* win32:113 (VK_F2) -> linux:60 (KEY_F2) -> qcode:Q_KEY_CODE_F2 (f2) */
|
||||
Q_KEY_CODE_F3, /* win32:114 (VK_F3) -> linux:61 (KEY_F3) -> qcode:Q_KEY_CODE_F3 (f3) */
|
||||
Q_KEY_CODE_F4, /* win32:115 (VK_F4) -> linux:62 (KEY_F4) -> qcode:Q_KEY_CODE_F4 (f4) */
|
||||
Q_KEY_CODE_F5, /* win32:116 (VK_F5) -> linux:63 (KEY_F5) -> qcode:Q_KEY_CODE_F5 (f5) */
|
||||
Q_KEY_CODE_F6, /* win32:117 (VK_F6) -> linux:64 (KEY_F6) -> qcode:Q_KEY_CODE_F6 (f6) */
|
||||
Q_KEY_CODE_F7, /* win32:118 (VK_F7) -> linux:65 (KEY_F7) -> qcode:Q_KEY_CODE_F7 (f7) */
|
||||
Q_KEY_CODE_F8, /* win32:119 (VK_F8) -> linux:66 (KEY_F8) -> qcode:Q_KEY_CODE_F8 (f8) */
|
||||
Q_KEY_CODE_F9, /* win32:120 (VK_F9) -> linux:67 (KEY_F9) -> qcode:Q_KEY_CODE_F9 (f9) */
|
||||
Q_KEY_CODE_F10, /* win32:121 (VK_F10) -> linux:68 (KEY_F10) -> qcode:Q_KEY_CODE_F10 (f10) */
|
||||
Q_KEY_CODE_F11, /* win32:122 (VK_F11) -> linux:87 (KEY_F11) -> qcode:Q_KEY_CODE_F11 (f11) */
|
||||
Q_KEY_CODE_F12, /* win32:123 (VK_F12) -> linux:88 (KEY_F12) -> qcode:Q_KEY_CODE_F12 (f12) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:124 (VK_F13) -> linux:183 (KEY_F13) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:125 (VK_F14) -> linux:184 (KEY_F14) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:126 (VK_F15) -> linux:185 (KEY_F15) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:127 (VK_F16) -> linux:186 (KEY_F16) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:128 (VK_F17) -> linux:187 (KEY_F17) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:129 (VK_F18) -> linux:188 (KEY_F18) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:130 (VK_F19) -> linux:189 (KEY_F19) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:131 (VK_F20) -> linux:190 (KEY_F20) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:132 (VK_F21) -> linux:191 (KEY_F21) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:133 (VK_F22) -> linux:192 (KEY_F22) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:134 (VK_F23) -> linux:193 (KEY_F23) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:135 (VK_F24) -> linux:194 (KEY_F24) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:136 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:137 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:138 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:139 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:140 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:141 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:142 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:143 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_NUM_LOCK, /* win32:144 (VK_NUMLOCK) -> linux:69 (KEY_NUMLOCK) -> qcode:Q_KEY_CODE_NUM_LOCK (num_lock) */
|
||||
Q_KEY_CODE_SCROLL_LOCK, /* win32:145 (VK_SCROLL) -> linux:70 (KEY_SCROLLLOCK) -> qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:146 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:147 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:148 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:149 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:150 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:151 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:152 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:153 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:154 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:155 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:156 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:157 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:158 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:159 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SHIFT, /* win32:160 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
|
||||
Q_KEY_CODE_SHIFT_R, /* win32:161 (VK_RSHIFT) -> linux:54 (KEY_RIGHTSHIFT) -> qcode:Q_KEY_CODE_SHIFT_R (shift_r) */
|
||||
Q_KEY_CODE_CTRL, /* win32:162 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
|
||||
Q_KEY_CODE_CTRL_R, /* win32:163 (VK_RCONTROL) -> linux:97 (KEY_RIGHTCTRL) -> qcode:Q_KEY_CODE_CTRL_R (ctrl_r) */
|
||||
Q_KEY_CODE_ALT, /* win32:164 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
|
||||
Q_KEY_CODE_ALT_R, /* win32:165 (VK_RMENU) -> linux:100 (KEY_RIGHTALT) -> qcode:Q_KEY_CODE_ALT_R (alt_r) */
|
||||
Q_KEY_CODE_AC_BACK, /* win32:166 (VK_BROWSER_BACK) -> linux:158 (KEY_BACK) -> qcode:Q_KEY_CODE_AC_BACK (ac_back) */
|
||||
Q_KEY_CODE_AC_FORWARD, /* win32:167 (VK_BROWSER_FORWARD) -> linux:159 (KEY_FORWARD) -> qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) */
|
||||
Q_KEY_CODE_AC_REFRESH, /* win32:168 (VK_BROWSER_REFRESH) -> linux:173 (KEY_REFRESH) -> qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) */
|
||||
Q_KEY_CODE_STOP, /* win32:169 (VK_BROWSER_STOP) -> linux:128 (KEY_STOP) -> qcode:Q_KEY_CODE_STOP (stop) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:170 (VK_BROWSER_SEARCH) -> linux:217 (KEY_SEARCH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:171 (VK_BROWSER_FAVOURITES) -> linux:364 (KEY_FAVORITES) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_AC_HOME, /* win32:172 (VK_BROWSER_HOME) -> linux:172 (KEY_HOMEPAGE) -> qcode:Q_KEY_CODE_AC_HOME (ac_home) */
|
||||
Q_KEY_CODE_AUDIOMUTE, /* win32:173 (VK_VOLUME_MUTE) -> linux:113 (KEY_MUTE) -> qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) */
|
||||
Q_KEY_CODE_VOLUMEDOWN, /* win32:174 (VK_VOLUME_DOWN) -> linux:114 (KEY_VOLUMEDOWN) -> qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) */
|
||||
Q_KEY_CODE_VOLUMEUP, /* win32:175 (VK_VOLUME_UP) -> linux:115 (KEY_VOLUMEUP) -> qcode:Q_KEY_CODE_VOLUMEUP (volumeup) */
|
||||
Q_KEY_CODE_AUDIONEXT, /* win32:176 (VK_MEDIA_NEXT_TRACK) -> linux:163 (KEY_NEXTSONG) -> qcode:Q_KEY_CODE_AUDIONEXT (audionext) */
|
||||
Q_KEY_CODE_AUDIOPREV, /* win32:177 (VK_MEDIA_PREV_TRACK) -> linux:165 (KEY_PREVIOUSSONG) -> qcode:Q_KEY_CODE_AUDIOPREV (audioprev) */
|
||||
Q_KEY_CODE_AUDIOSTOP, /* win32:178 (VK_MEDIA_STOP) -> linux:166 (KEY_STOPCD) -> qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) */
|
||||
Q_KEY_CODE_AUDIOPLAY, /* win32:179 (VK_MEDIA_PLAY_PAUSE) -> linux:164 (KEY_PLAYPAUSE) -> qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:180 (VK_LAUNCH_MAIL) -> linux:215 (KEY_EMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:181 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:182 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:183 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:184 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:185 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_SEMICOLON, /* win32:186 (VK_OEM_1) -> linux:39 (KEY_SEMICOLON) -> qcode:Q_KEY_CODE_SEMICOLON (semicolon) */
|
||||
Q_KEY_CODE_EQUAL, /* win32:187 (VK_OEM_PLUS) -> linux:13 (KEY_EQUAL) -> qcode:Q_KEY_CODE_EQUAL (equal) */
|
||||
Q_KEY_CODE_COMMA, /* win32:188 (VK_OEM_COMMA) -> linux:51 (KEY_COMMA) -> qcode:Q_KEY_CODE_COMMA (comma) */
|
||||
Q_KEY_CODE_MINUS, /* win32:189 (VK_OEM_MINUS) -> linux:12 (KEY_MINUS) -> qcode:Q_KEY_CODE_MINUS (minus) */
|
||||
Q_KEY_CODE_DOT, /* win32:190 (VK_OEM_PERIOD) -> linux:52 (KEY_DOT) -> qcode:Q_KEY_CODE_DOT (dot) */
|
||||
Q_KEY_CODE_SLASH, /* win32:191 (VK_OEM_2) -> linux:53 (KEY_SLASH) -> qcode:Q_KEY_CODE_SLASH (slash) */
|
||||
Q_KEY_CODE_GRAVE_ACCENT, /* win32:192 (VK_OEM_3) -> linux:41 (KEY_GRAVE) -> qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:193 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:194 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:195 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:196 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:197 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:198 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:199 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:200 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:201 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:202 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:203 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:204 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:205 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:206 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:207 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:208 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:209 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:210 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:211 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:212 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:213 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:214 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:215 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:216 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:217 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:218 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_BRACKET_LEFT, /* win32:219 (VK_OEM_4) -> linux:26 (KEY_LEFTBRACE) -> qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) */
|
||||
Q_KEY_CODE_BACKSLASH, /* win32:220 (VK_OEM_5) -> linux:43 (KEY_BACKSLASH) -> qcode:Q_KEY_CODE_BACKSLASH (backslash) */
|
||||
Q_KEY_CODE_BRACKET_RIGHT, /* win32:221 (VK_OEM_6) -> linux:27 (KEY_RIGHTBRACE) -> qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) */
|
||||
Q_KEY_CODE_APOSTROPHE, /* win32:222 (VK_OEM_7) -> linux:40 (KEY_APOSTROPHE) -> qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:223 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:224 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_LESS, /* win32:225 (VK_OEM_102) -> linux:86 (KEY_102ND) -> qcode:Q_KEY_CODE_LESS (less) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:226 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:227 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:228 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:229 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:230 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:231 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:232 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:233 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:234 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:235 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:236 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:237 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:238 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:239 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:240 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:241 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:242 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:243 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:244 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:245 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:246 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:247 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:248 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:249 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:250 (VK_PLAY) -> linux:207 (KEY_PLAY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
Q_KEY_CODE_UNMAPPED, /* win32:251 (VK_ZOOM) -> linux:372 (KEY_ZOOM) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
|
||||
};
|
||||
|
|
|
@ -18,5 +18,5 @@
|
|||
|
||||
extern const std::map<const QKeyCode, unsigned short> qemu_input_map_qcode_to_qnum;
|
||||
int qemu_input_qcode_to_number(const QKeyCode value);
|
||||
int qemu_input_key_value_to_number(const KeyValue *value);
|
||||
int qemu_input_key_value_to_scancode(const KeyValue *value, bool down, int *codes);
|
||||
int qemu_input_key_value_to_number(const KeyValue* value);
|
||||
int qemu_input_key_value_to_scancode(const KeyValue* value, bool down, int* codes);
|
||||
|
|
|
@ -24,133 +24,149 @@
|
|||
//#include "qemu/cutils.h"
|
||||
#include <cassert>
|
||||
|
||||
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
|
||||
size_t offset, const void *buf, size_t bytes)
|
||||
size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
|
||||
size_t offset, const void* buf, size_t bytes)
|
||||
{
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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 {
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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
|
||||
{
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
}
|
||||
|
||||
size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
size_t offset, void *buf, size_t bytes)
|
||||
size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
|
||||
size_t offset, void* buf, size_t bytes)
|
||||
{
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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 {
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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
|
||||
{
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
}
|
||||
|
||||
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
size_t offset, int fillc, size_t bytes)
|
||||
size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
|
||||
size_t offset, int fillc, size_t bytes)
|
||||
{
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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 {
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
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
|
||||
{
|
||||
offset -= iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(offset == 0);
|
||||
return done;
|
||||
}
|
||||
|
||||
size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
|
||||
size_t iov_size(const struct iovec* iov, const unsigned int iov_cnt)
|
||||
{
|
||||
size_t len;
|
||||
unsigned int i;
|
||||
size_t len;
|
||||
unsigned int i;
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < iov_cnt; i++) {
|
||||
len += iov[i].iov_len;
|
||||
}
|
||||
return len;
|
||||
len = 0;
|
||||
for (i = 0; i < iov_cnt; i++)
|
||||
{
|
||||
len += iov[i].iov_len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
|
||||
const struct iovec *iov, unsigned int iov_cnt,
|
||||
size_t offset, size_t bytes)
|
||||
unsigned iov_copy(struct iovec* dst_iov, unsigned int dst_iov_cnt,
|
||||
const struct iovec* iov, unsigned int iov_cnt,
|
||||
size_t offset, size_t bytes)
|
||||
{
|
||||
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) {
|
||||
offset -= iov[i].iov_len;
|
||||
continue;
|
||||
}
|
||||
len = MIN(bytes, iov[i].iov_len - offset);
|
||||
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)
|
||||
{
|
||||
offset -= iov[i].iov_len;
|
||||
continue;
|
||||
}
|
||||
len = MIN(bytes, iov[i].iov_len - offset);
|
||||
|
||||
dst_iov[j].iov_base = (char *)iov[i].iov_base + offset;
|
||||
dst_iov[j].iov_len = len;
|
||||
j++;
|
||||
bytes -= len;
|
||||
offset = 0;
|
||||
}
|
||||
assert(offset == 0);
|
||||
return j;
|
||||
dst_iov[j].iov_base = (char*)iov[i].iov_base + offset;
|
||||
dst_iov[j].iov_len = len;
|
||||
j++;
|
||||
bytes -= len;
|
||||
offset = 0;
|
||||
}
|
||||
assert(offset == 0);
|
||||
return j;
|
||||
}
|
||||
|
||||
/* io vectors */
|
||||
|
||||
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
|
||||
void qemu_iovec_init(QEMUIOVector* qiov, int alloc_hint)
|
||||
{
|
||||
qiov->iov = my_g_new(struct iovec, alloc_hint);
|
||||
qiov->niov = 0;
|
||||
qiov->nalloc = alloc_hint;
|
||||
qiov->size = 0;
|
||||
qiov->iov = my_g_new(struct iovec, alloc_hint);
|
||||
qiov->niov = 0;
|
||||
qiov->nalloc = alloc_hint;
|
||||
qiov->size = 0;
|
||||
}
|
||||
|
||||
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
|
||||
void qemu_iovec_init_external(QEMUIOVector* qiov, struct iovec* iov, int niov)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
qiov->iov = iov;
|
||||
qiov->niov = niov;
|
||||
qiov->nalloc = -1;
|
||||
qiov->size = 0;
|
||||
for (i = 0; i < niov; i++)
|
||||
qiov->size += iov[i].iov_len;
|
||||
qiov->iov = iov;
|
||||
qiov->niov = niov;
|
||||
qiov->nalloc = -1;
|
||||
qiov->size = 0;
|
||||
for (i = 0; i < niov; i++)
|
||||
qiov->size += iov[i].iov_len;
|
||||
}
|
||||
|
||||
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
|
||||
void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len)
|
||||
{
|
||||
assert(qiov->nalloc != -1);
|
||||
assert(qiov->nalloc != -1);
|
||||
|
||||
if (qiov->niov == qiov->nalloc) {
|
||||
qiov->nalloc = 2 * qiov->nalloc + 1;
|
||||
qiov->iov = my_g_renew(struct iovec, qiov->iov, qiov->nalloc);
|
||||
}
|
||||
qiov->iov[qiov->niov].iov_base = base;
|
||||
qiov->iov[qiov->niov].iov_len = len;
|
||||
qiov->size += len;
|
||||
++qiov->niov;
|
||||
if (qiov->niov == qiov->nalloc)
|
||||
{
|
||||
qiov->nalloc = 2 * qiov->nalloc + 1;
|
||||
qiov->iov = my_g_renew(struct iovec, qiov->iov, qiov->nalloc);
|
||||
}
|
||||
qiov->iov[qiov->niov].iov_base = base;
|
||||
qiov->iov[qiov->niov].iov_len = len;
|
||||
qiov->size += len;
|
||||
++qiov->niov;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -163,30 +179,35 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
|
|||
* of src".
|
||||
* Only vector pointers are processed, not the actual data buffers.
|
||||
*/
|
||||
size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
|
||||
struct iovec *src_iov, unsigned int src_cnt,
|
||||
size_t soffset, size_t sbytes)
|
||||
size_t qemu_iovec_concat_iov(QEMUIOVector* dst,
|
||||
struct iovec* src_iov, unsigned int src_cnt,
|
||||
size_t soffset, size_t sbytes)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t done;
|
||||
unsigned int i;
|
||||
size_t done;
|
||||
|
||||
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) {
|
||||
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 {
|
||||
soffset -= src_iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(soffset == 0); /* offset beyond end of src */
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
soffset -= src_iov[i].iov_len;
|
||||
}
|
||||
}
|
||||
assert(soffset == 0); /* offset beyond end of src */
|
||||
|
||||
return done;
|
||||
return done;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -199,10 +220,10 @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
|
|||
* of src".
|
||||
* Only vector pointers are processed, not the actual data buffers.
|
||||
*/
|
||||
void qemu_iovec_concat(QEMUIOVector *dst,
|
||||
QEMUIOVector *src, size_t soffset, size_t sbytes)
|
||||
void qemu_iovec_concat(QEMUIOVector* dst,
|
||||
QEMUIOVector* src, size_t soffset, size_t sbytes)
|
||||
{
|
||||
qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes);
|
||||
qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -226,40 +247,40 @@ void qemu_iovec_concat(QEMUIOVector *dst,
|
|||
return true;
|
||||
}*/
|
||||
|
||||
void qemu_iovec_destroy(QEMUIOVector *qiov)
|
||||
void qemu_iovec_destroy(QEMUIOVector* qiov)
|
||||
{
|
||||
assert(qiov->nalloc != -1);
|
||||
assert(qiov->nalloc != -1);
|
||||
|
||||
qemu_iovec_reset(qiov);
|
||||
my_g_free(qiov->iov);
|
||||
qiov->nalloc = 0;
|
||||
qiov->iov = NULL;
|
||||
qemu_iovec_reset(qiov);
|
||||
my_g_free(qiov->iov);
|
||||
qiov->nalloc = 0;
|
||||
qiov->iov = NULL;
|
||||
}
|
||||
|
||||
void qemu_iovec_reset(QEMUIOVector *qiov)
|
||||
void qemu_iovec_reset(QEMUIOVector* qiov)
|
||||
{
|
||||
assert(qiov->nalloc != -1);
|
||||
assert(qiov->nalloc != -1);
|
||||
|
||||
qiov->niov = 0;
|
||||
qiov->size = 0;
|
||||
qiov->niov = 0;
|
||||
qiov->size = 0;
|
||||
}
|
||||
|
||||
size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
|
||||
void *buf, size_t bytes)
|
||||
size_t qemu_iovec_to_buf(QEMUIOVector* qiov, size_t offset,
|
||||
void* buf, size_t bytes)
|
||||
{
|
||||
return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes);
|
||||
return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes);
|
||||
}
|
||||
|
||||
size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
|
||||
const void *buf, size_t bytes)
|
||||
size_t qemu_iovec_from_buf(QEMUIOVector* qiov, size_t offset,
|
||||
const void* buf, size_t bytes)
|
||||
{
|
||||
return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes);
|
||||
return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes);
|
||||
}
|
||||
|
||||
size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
|
||||
int fillc, size_t bytes)
|
||||
size_t qemu_iovec_memset(QEMUIOVector* qiov, size_t offset,
|
||||
int fillc, size_t bytes)
|
||||
{
|
||||
return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
|
||||
return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,118 +293,132 @@ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
|
|||
* @b: I/O vector
|
||||
* @ret: Offset to first mismatching byte or -1 if match
|
||||
*/
|
||||
ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
|
||||
ssize_t qemu_iovec_compare(QEMUIOVector* a, QEMUIOVector* b)
|
||||
{
|
||||
int i;
|
||||
ssize_t offset = 0;
|
||||
int i;
|
||||
ssize_t offset = 0;
|
||||
|
||||
assert(a->niov == b->niov);
|
||||
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->niov == b->niov);
|
||||
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++) {
|
||||
len++;
|
||||
}
|
||||
assert(a->iov[i].iov_len == b->iov[i].iov_len);
|
||||
while (len < a->iov[i].iov_len && *p++ == *q++)
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
offset += len;
|
||||
|
||||
if (len != a->iov[i].iov_len) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (len != a->iov[i].iov_len)
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int src_index;
|
||||
struct iovec *src_iov;
|
||||
void *dest_base;
|
||||
typedef struct
|
||||
{
|
||||
int src_index;
|
||||
struct iovec* src_iov;
|
||||
void* dest_base;
|
||||
} IOVectorSortElem;
|
||||
|
||||
static int sortelem_cmp_src_base(const void *a, const void *b)
|
||||
static int sortelem_cmp_src_base(const void* a, const void* b)
|
||||
{
|
||||
const IOVectorSortElem *elem_a = (const IOVectorSortElem *)a;
|
||||
const IOVectorSortElem *elem_b = (const IOVectorSortElem *)b;
|
||||
const IOVectorSortElem* elem_a = (const IOVectorSortElem*)a;
|
||||
const IOVectorSortElem* elem_b = (const IOVectorSortElem*)b;
|
||||
|
||||
/* Don't overflow */
|
||||
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) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
/* Don't overflow */
|
||||
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)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int sortelem_cmp_src_index(const void *a, const void *b)
|
||||
static int sortelem_cmp_src_index(const void* a, const void* b)
|
||||
{
|
||||
const IOVectorSortElem *elem_a = (const IOVectorSortElem *)a;
|
||||
const IOVectorSortElem *elem_b = (const IOVectorSortElem *)b;
|
||||
const IOVectorSortElem* elem_a = (const IOVectorSortElem*)a;
|
||||
const IOVectorSortElem* elem_b = (const IOVectorSortElem*)b;
|
||||
|
||||
return elem_a->src_index - elem_b->src_index;
|
||||
return elem_a->src_index - elem_b->src_index;
|
||||
}
|
||||
|
||||
size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
|
||||
size_t bytes)
|
||||
size_t iov_discard_front(struct iovec** iov, unsigned int* iov_cnt,
|
||||
size_t bytes)
|
||||
{
|
||||
size_t total = 0;
|
||||
struct iovec *cur;
|
||||
size_t total = 0;
|
||||
struct iovec* cur;
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes -= cur->iov_len;
|
||||
total += cur->iov_len;
|
||||
*iov_cnt -= 1;
|
||||
}
|
||||
bytes -= cur->iov_len;
|
||||
total += cur->iov_len;
|
||||
*iov_cnt -= 1;
|
||||
}
|
||||
|
||||
*iov = cur;
|
||||
return total;
|
||||
*iov = cur;
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
|
||||
size_t bytes)
|
||||
size_t iov_discard_back(struct iovec* iov, unsigned int* iov_cnt,
|
||||
size_t bytes)
|
||||
{
|
||||
size_t total = 0;
|
||||
struct iovec *cur;
|
||||
size_t total = 0;
|
||||
struct iovec* cur;
|
||||
|
||||
if (*iov_cnt == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (*iov_cnt == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur = iov + (*iov_cnt - 1);
|
||||
cur = iov + (*iov_cnt - 1);
|
||||
|
||||
while (*iov_cnt > 0) {
|
||||
if (cur->iov_len > bytes) {
|
||||
cur->iov_len -= bytes;
|
||||
total += bytes;
|
||||
break;
|
||||
}
|
||||
while (*iov_cnt > 0)
|
||||
{
|
||||
if (cur->iov_len > bytes)
|
||||
{
|
||||
cur->iov_len -= bytes;
|
||||
total += bytes;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes -= cur->iov_len;
|
||||
total += cur->iov_len;
|
||||
cur--;
|
||||
*iov_cnt -= 1;
|
||||
}
|
||||
bytes -= cur->iov_len;
|
||||
total += cur->iov_len;
|
||||
cur--;
|
||||
*iov_cnt -= 1;
|
||||
}
|
||||
|
||||
return total;
|
||||
return total;
|
||||
}
|
||||
|
||||
void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes)
|
||||
void qemu_iovec_discard_back(QEMUIOVector* qiov, size_t bytes)
|
||||
{
|
||||
unsigned int niov = qiov->niov;
|
||||
unsigned int niov = qiov->niov;
|
||||
|
||||
assert(qiov->size >= bytes);
|
||||
assert(iov_discard_back(qiov->iov, &niov, bytes) == bytes);
|
||||
assert(qiov->size >= bytes);
|
||||
assert(iov_discard_back(qiov->iov, &niov, bytes) == bytes);
|
||||
|
||||
qiov->niov = niov;
|
||||
qiov->size -= bytes;
|
||||
qiov->niov = niov;
|
||||
qiov->size -= bytes;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
#define IOV_H
|
||||
|
||||
#if !defined(_BITS_UIO_H) && !defined(__iovec_defined) /* /usr/include/bits/uio.h */
|
||||
struct iovec {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
struct iovec
|
||||
{
|
||||
void* iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -25,7 +26,7 @@ struct iovec {
|
|||
* count and return data size, in bytes, of an iovec
|
||||
* starting at `iov' of `iov_cnt' number of elements.
|
||||
*/
|
||||
size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
|
||||
size_t iov_size(const struct iovec* iov, const unsigned int iov_cnt);
|
||||
|
||||
/**
|
||||
* Copy from single continuous buffer to scatter-gather vector of buffers
|
||||
|
@ -44,35 +45,41 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
|
|||
* such "large" value is -1 (sinice size_t is unsigned),
|
||||
* so specifying `-1' as `bytes' means 'up to the end of iovec'.
|
||||
*/
|
||||
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
|
||||
size_t offset, const void *buf, size_t bytes);
|
||||
size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
size_t offset, void *buf, size_t bytes);
|
||||
size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
|
||||
size_t offset, const void* buf, size_t bytes);
|
||||
size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
|
||||
size_t offset, void* buf, size_t bytes);
|
||||
|
||||
static inline size_t
|
||||
iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
|
||||
size_t offset, const void *buf, size_t bytes)
|
||||
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) {
|
||||
memcpy((char *)iov[0].iov_base + offset, buf, bytes);
|
||||
return bytes;
|
||||
} else {
|
||||
return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
|
||||
}
|
||||
if (__builtin_constant_p(bytes) && iov_cnt &&
|
||||
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
|
||||
{
|
||||
memcpy((char*)iov[0].iov_base + offset, buf, bytes);
|
||||
return bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
size_t offset, void *buf, size_t bytes)
|
||||
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) {
|
||||
memcpy(buf, (char *)iov[0].iov_base + offset, bytes);
|
||||
return bytes;
|
||||
} else {
|
||||
return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
|
||||
}
|
||||
if (__builtin_constant_p(bytes) && iov_cnt &&
|
||||
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
|
||||
{
|
||||
memcpy(buf, (char*)iov[0].iov_base + offset, bytes);
|
||||
return bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,8 +92,8 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
|
|||
* min(size, iov_size(iov) - offset).
|
||||
* Again, it is okay to use large value for `bytes' to mean "up to the end".
|
||||
*/
|
||||
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
size_t offset, int fillc, size_t bytes);
|
||||
size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
|
||||
size_t offset, int fillc, size_t bytes);
|
||||
|
||||
/*
|
||||
* Send/recv data from/to iovec buffers directly
|
||||
|
@ -106,29 +113,29 @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
|
|||
* For iov_send_recv() _whole_ area being sent or received
|
||||
* should be within the iovec, not only beginning of it.
|
||||
*/
|
||||
ssize_t iov_send_recv(int sockfd, const struct iovec *iov, unsigned iov_cnt,
|
||||
size_t offset, size_t bytes, bool do_send);
|
||||
ssize_t iov_send_recv(int sockfd, const struct iovec* iov, unsigned iov_cnt,
|
||||
size_t offset, size_t bytes, bool do_send);
|
||||
#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
|
||||
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
|
||||
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
|
||||
#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
|
||||
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
|
||||
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
|
||||
|
||||
/**
|
||||
* Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements
|
||||
* in file `fp', prefixing each line with `prefix' and processing not more
|
||||
* than `limit' data bytes.
|
||||
*/
|
||||
void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
|
||||
FILE *fp, const char *prefix, size_t limit);
|
||||
void iov_hexdump(const struct iovec* iov, const unsigned int iov_cnt,
|
||||
FILE* fp, const char* prefix, size_t limit);
|
||||
|
||||
/*
|
||||
* Partial copy of vector from iov to dst_iov (data is not copied).
|
||||
* dst_iov overlaps iov at a specified offset.
|
||||
* size of dst_iov is at most bytes. dst vector count is returned.
|
||||
*/
|
||||
unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
|
||||
const struct iovec *iov, unsigned int iov_cnt,
|
||||
size_t offset, size_t bytes);
|
||||
unsigned iov_copy(struct iovec* dst_iov, unsigned int dst_iov_cnt,
|
||||
const struct iovec* iov, unsigned int iov_cnt,
|
||||
size_t offset, size_t bytes);
|
||||
|
||||
/*
|
||||
* Remove a given number of bytes from the front or back of a vector.
|
||||
|
@ -138,37 +145,38 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
|
|||
* The number of bytes actually discarded is returned. This number may be
|
||||
* smaller than requested if the vector is too small.
|
||||
*/
|
||||
size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
|
||||
size_t bytes);
|
||||
size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
|
||||
size_t bytes);
|
||||
size_t iov_discard_front(struct iovec** iov, unsigned int* iov_cnt,
|
||||
size_t bytes);
|
||||
size_t iov_discard_back(struct iovec* iov, unsigned int* iov_cnt,
|
||||
size_t bytes);
|
||||
|
||||
typedef struct QEMUIOVector {
|
||||
struct iovec *iov;
|
||||
int niov;
|
||||
int nalloc;
|
||||
size_t size;
|
||||
typedef struct QEMUIOVector
|
||||
{
|
||||
struct iovec* iov;
|
||||
int niov;
|
||||
int nalloc;
|
||||
size_t size;
|
||||
} QEMUIOVector;
|
||||
|
||||
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
|
||||
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
|
||||
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
|
||||
void qemu_iovec_concat(QEMUIOVector *dst,
|
||||
QEMUIOVector *src, size_t soffset, size_t sbytes);
|
||||
size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
|
||||
struct iovec *src_iov, unsigned int src_cnt,
|
||||
size_t soffset, size_t sbytes);
|
||||
bool qemu_iovec_is_zero(QEMUIOVector *qiov);
|
||||
void qemu_iovec_destroy(QEMUIOVector *qiov);
|
||||
void qemu_iovec_reset(QEMUIOVector *qiov);
|
||||
size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
|
||||
void *buf, size_t bytes);
|
||||
size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
|
||||
const void *buf, size_t bytes);
|
||||
size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
|
||||
int fillc, size_t bytes);
|
||||
ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b);
|
||||
void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf);
|
||||
void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes);
|
||||
void qemu_iovec_init(QEMUIOVector* qiov, int alloc_hint);
|
||||
void qemu_iovec_init_external(QEMUIOVector* qiov, struct iovec* iov, int niov);
|
||||
void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len);
|
||||
void qemu_iovec_concat(QEMUIOVector* dst,
|
||||
QEMUIOVector* src, size_t soffset, size_t sbytes);
|
||||
size_t qemu_iovec_concat_iov(QEMUIOVector* dst,
|
||||
struct iovec* src_iov, unsigned int src_cnt,
|
||||
size_t soffset, size_t sbytes);
|
||||
bool qemu_iovec_is_zero(QEMUIOVector* qiov);
|
||||
void qemu_iovec_destroy(QEMUIOVector* qiov);
|
||||
void qemu_iovec_reset(QEMUIOVector* qiov);
|
||||
size_t qemu_iovec_to_buf(QEMUIOVector* qiov, size_t offset,
|
||||
void* buf, size_t bytes);
|
||||
size_t qemu_iovec_from_buf(QEMUIOVector* qiov, size_t offset,
|
||||
const void* buf, size_t bytes);
|
||||
size_t qemu_iovec_memset(QEMUIOVector* qiov, size_t offset,
|
||||
int fillc, size_t bytes);
|
||||
ssize_t qemu_iovec_compare(QEMUIOVector* a, QEMUIOVector* b);
|
||||
void qemu_iovec_clone(QEMUIOVector* dest, const QEMUIOVector* src, void* buf);
|
||||
void qemu_iovec_discard_back(QEMUIOVector* qiov, size_t bytes);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -83,390 +83,472 @@
|
|||
/*
|
||||
* List definitions.
|
||||
*/
|
||||
#define QLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
#define QLIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define QLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
#define QLIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define QLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define QLIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* le_next; /* next element */ \
|
||||
struct type** le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
#define QLIST_INIT(head) do { \
|
||||
(head)->lh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QLIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
(head)->lh_first = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QLIST_SWAP(dstlist, srclist, field) do { \
|
||||
void *tmplist; \
|
||||
tmplist = (srclist)->lh_first; \
|
||||
(srclist)->lh_first = (dstlist)->lh_first; \
|
||||
if ((srclist)->lh_first != NULL) { \
|
||||
(srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \
|
||||
} \
|
||||
(dstlist)->lh_first = tmplist; \
|
||||
if ((dstlist)->lh_first != NULL) { \
|
||||
(dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QLIST_SWAP(dstlist, srclist, field) \
|
||||
do \
|
||||
{ \
|
||||
void* tmplist; \
|
||||
tmplist = (srclist)->lh_first; \
|
||||
(srclist)->lh_first = (dstlist)->lh_first; \
|
||||
if ((srclist)->lh_first != NULL) \
|
||||
{ \
|
||||
(srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \
|
||||
} \
|
||||
(dstlist)->lh_first = tmplist; \
|
||||
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 { \
|
||||
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||
(listelm)->field.le_next->field.le_prev = \
|
||||
&(elm)->field.le_next; \
|
||||
(listelm)->field.le_next = (elm); \
|
||||
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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; \
|
||||
(listelm)->field.le_next = (elm); \
|
||||
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#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_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 { \
|
||||
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_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 { \
|
||||
if ((elm)->field.le_next != NULL) \
|
||||
(elm)->field.le_next->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QLIST_REMOVE(elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((elm)->field.le_next != NULL) \
|
||||
(elm)->field.le_next->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QLIST_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.le_next))
|
||||
#define QLIST_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.le_next))
|
||||
|
||||
#define QLIST_FOREACH_SAFE(var, head, field, next_var) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var) && ((next_var) = ((var)->field.le_next), 1); \
|
||||
(var) = (next_var))
|
||||
#define QLIST_FOREACH_SAFE(var, head, field, next_var) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var) && ((next_var) = ((var)->field.le_next), 1); \
|
||||
(var) = (next_var))
|
||||
|
||||
/*
|
||||
* List access methods.
|
||||
*/
|
||||
#define QLIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define QLIST_FIRST(head) ((head)->lh_first)
|
||||
#define QLIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
#define QLIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define QLIST_FIRST(head) ((head)->lh_first)
|
||||
#define QLIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
|
||||
/*
|
||||
* Singly-linked List definitions.
|
||||
*/
|
||||
#define QSLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
#define QSLIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define QSLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
#define QSLIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define QSLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
#define QSLIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define QSLIST_INIT(head) do { \
|
||||
(head)->slh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QSLIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
(head)->slh_first = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#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_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 { \
|
||||
(elm)->field.sle_next = (head)->slh_first; \
|
||||
(head)->slh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
typeof(elm) save_sle_next; \
|
||||
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_INSERT_HEAD_ATOMIC(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
typeof(elm) save_sle_next; \
|
||||
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 { \
|
||||
(dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
(slistelm)->field.sle_next = \
|
||||
QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QSLIST_REMOVE_AFTER(slistelm, field) \
|
||||
do \
|
||||
{ \
|
||||
(slistelm)->field.sle_next = \
|
||||
QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QSLIST_FOREACH(var, head, field) \
|
||||
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
|
||||
#define QSLIST_FOREACH(var, head, field) \
|
||||
for ((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
|
||||
|
||||
#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = QSLIST_FIRST((head)); \
|
||||
(var) && ((tvar) = QSLIST_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = QSLIST_FIRST((head)); \
|
||||
(var) && ((tvar) = QSLIST_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
/*
|
||||
* Singly-linked List access methods.
|
||||
*/
|
||||
#define QSLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define QSLIST_FIRST(head) ((head)->slh_first)
|
||||
#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
#define QSLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define QSLIST_FIRST(head) ((head)->slh_first)
|
||||
#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
|
||||
/*
|
||||
* Simple queue definitions.
|
||||
*/
|
||||
#define QSIMPLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sqh_first; /* first element */ \
|
||||
struct type **sqh_last; /* addr of last next element */ \
|
||||
}
|
||||
#define QSIMPLEQ_HEAD(name, type) \
|
||||
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 }
|
||||
#define QSIMPLEQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).sqh_first \
|
||||
}
|
||||
|
||||
#define QSIMPLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sqe_next; /* next element */ \
|
||||
}
|
||||
#define QSIMPLEQ_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* sqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple queue functions.
|
||||
*/
|
||||
#define QSIMPLEQ_INIT(head) do { \
|
||||
(head)->sqh_first = NULL; \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
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_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 { \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
*(head)->sqh_last = (elm); \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
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_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 { \
|
||||
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
QSIMPLEQ_INIT(removed); \
|
||||
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; \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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) \
|
||||
{ \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} \
|
||||
(removed)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->sqh_first == (elm)) { \
|
||||
QSIMPLEQ_REMOVE_HEAD((head), field); \
|
||||
} else { \
|
||||
struct type *curelm = (head)->sqh_first; \
|
||||
while (curelm->field.sqe_next != (elm)) \
|
||||
curelm = curelm->field.sqe_next; \
|
||||
if ((curelm->field.sqe_next = \
|
||||
curelm->field.sqe_next->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(curelm)->field.sqe_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QSIMPLEQ_REMOVE(head, elm, type, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((head)->sqh_first == (elm)) \
|
||||
{ \
|
||||
QSIMPLEQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct type* curelm = (head)->sqh_first; \
|
||||
while (curelm->field.sqe_next != (elm)) \
|
||||
curelm = curelm->field.sqe_next; \
|
||||
if ((curelm->field.sqe_next = \
|
||||
curelm->field.sqe_next->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(curelm)->field.sqe_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QSIMPLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.sqe_next))
|
||||
#define QSIMPLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.sqe_next))
|
||||
|
||||
#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var) && ((next = ((var)->field.sqe_next)), 1); \
|
||||
(var) = (next))
|
||||
#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var) && ((next = ((var)->field.sqe_next)), 1); \
|
||||
(var) = (next))
|
||||
|
||||
#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)); \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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)); \
|
||||
} \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QSIMPLEQ_LAST(head, type, field) \
|
||||
(QSIMPLEQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
((struct type *)(void *) \
|
||||
((char *)((head)->sqh_last) - offsetof(struct type, field))))
|
||||
#define QSIMPLEQ_LAST(head, type, field) \
|
||||
(QSIMPLEQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
((struct type*)(void*)((char*)((head)->sqh_last) - offsetof(struct type, field))))
|
||||
|
||||
/*
|
||||
* Simple queue access methods.
|
||||
*/
|
||||
#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
|
||||
#define QSIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
|
||||
#define QSIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define Q_TAILQ_HEAD(name, type, qual) \
|
||||
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 Q_TAILQ_HEAD(name, type, qual) \
|
||||
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 }
|
||||
#define QTAILQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).tqh_first \
|
||||
}
|
||||
|
||||
#define Q_TAILQ_ENTRY(type, qual) \
|
||||
struct { \
|
||||
qual type *tqe_next; /* next element */ \
|
||||
qual type *qual *tqe_prev; /* address of previous next element */\
|
||||
}
|
||||
#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,)
|
||||
#define Q_TAILQ_ENTRY(type, qual) \
|
||||
struct \
|
||||
{ \
|
||||
qual type* tqe_next; /* next element */ \
|
||||
qual type* qual* tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type, )
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define QTAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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 { \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#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_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 { \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#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_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 { \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
(elm)->field.tqe_prev = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define QTAILQ_REMOVE(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
(elm)->field.tqe_prev = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define QTAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
#define QTAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var) && ((next_var) = ((var)->field.tqe_next), 1); \
|
||||
(var) = (next_var))
|
||||
#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var) && ((next_var) = ((var)->field.tqe_next), 1); \
|
||||
(var) = (next_var))
|
||||
|
||||
#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
for ((var) = (*(((struct headname*)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname*)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define QTAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define QTAILQ_IN_USE(elm, field) ((elm)->field.tqe_prev != NULL)
|
||||
#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define QTAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define QTAILQ_IN_USE(elm, field) ((elm)->field.tqe_prev != NULL)
|
||||
|
||||
#define QTAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
(*(((struct headname*)((head)->tqh_last))->tqh_last))
|
||||
#define QTAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
(*(((struct headname*)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define field_at_offset(base, offset, type) \
|
||||
((type) (((char *) (base)) + (offset)))
|
||||
#define field_at_offset(base, offset, type) \
|
||||
((type)(((char*)(base)) + (offset)))
|
||||
|
||||
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)
|
||||
#define dummy_qe ((DUMMY_Q_ENTRY *) 0)
|
||||
#define dummy_q ((DUMMY_Q*)0)
|
||||
#define dummy_qe ((DUMMY_Q_ENTRY*)0)
|
||||
|
||||
/*
|
||||
* Offsets of layout of a tail queue head.
|
||||
*/
|
||||
#define QTAILQ_FIRST_OFFSET (offsetof(typeof(dummy_q->head), tqh_first))
|
||||
#define QTAILQ_LAST_OFFSET (offsetof(typeof(dummy_q->head), tqh_last))
|
||||
#define QTAILQ_LAST_OFFSET (offsetof(typeof(dummy_q->head), tqh_last))
|
||||
/*
|
||||
* Raw access of elements of a tail queue
|
||||
*/
|
||||
#define QTAILQ_RAW_FIRST(head) \
|
||||
(*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **))
|
||||
#define QTAILQ_RAW_TQH_LAST(head) \
|
||||
(*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***))
|
||||
#define QTAILQ_RAW_FIRST(head) \
|
||||
(*field_at_offset(head, QTAILQ_FIRST_OFFSET, void**))
|
||||
#define QTAILQ_RAW_TQH_LAST(head) \
|
||||
(*field_at_offset(head, QTAILQ_LAST_OFFSET, void***))
|
||||
|
||||
/*
|
||||
* Offsets of layout of a tail queue element.
|
||||
|
@ -477,25 +559,27 @@ struct DUMMY_Q {
|
|||
/*
|
||||
* Raw access of elements of a tail entry
|
||||
*/
|
||||
#define QTAILQ_RAW_NEXT(elm, entry) \
|
||||
(*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **))
|
||||
#define QTAILQ_RAW_TQE_PREV(elm, entry) \
|
||||
(*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***))
|
||||
#define QTAILQ_RAW_NEXT(elm, entry) \
|
||||
(*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void**))
|
||||
#define QTAILQ_RAW_TQE_PREV(elm, entry) \
|
||||
(*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void***))
|
||||
/*
|
||||
* Tail queue tranversal using pointer arithmetic.
|
||||
*/
|
||||
#define QTAILQ_RAW_FOREACH(elm, head, entry) \
|
||||
for ((elm) = QTAILQ_RAW_FIRST(head); \
|
||||
(elm); \
|
||||
(elm) = QTAILQ_RAW_NEXT(elm, entry))
|
||||
#define QTAILQ_RAW_FOREACH(elm, head, entry) \
|
||||
for ((elm) = QTAILQ_RAW_FIRST(head); \
|
||||
(elm); \
|
||||
(elm) = QTAILQ_RAW_NEXT(elm, entry))
|
||||
/*
|
||||
* Tail queue insertion using pointer arithmetic.
|
||||
*/
|
||||
#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); \
|
||||
QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#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); \
|
||||
QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#endif /* QEMU_SYS_QUEUE_H */
|
||||
|
|
|
@ -26,241 +26,241 @@
|
|||
#include "queue.h"
|
||||
|
||||
#define USB_TOKEN_SETUP 0x2d
|
||||
#define USB_TOKEN_IN 0x69 /* device -> host */
|
||||
#define USB_TOKEN_OUT 0xe1 /* host -> device */
|
||||
#define USB_TOKEN_IN 0x69 /* device -> host */
|
||||
#define USB_TOKEN_OUT 0xe1 /* host -> device */
|
||||
|
||||
/* specific usb messages, also sent in the 'pid' parameter */
|
||||
#define USB_MSG_ATTACH 0x100
|
||||
#define USB_MSG_DETACH 0x101
|
||||
#define USB_MSG_RESET 0x102
|
||||
#define USB_MSG_ATTACH 0x100
|
||||
#define USB_MSG_DETACH 0x101
|
||||
#define USB_MSG_RESET 0x102
|
||||
|
||||
#define USB_RET_SUCCESS (0)
|
||||
#define USB_RET_NODEV (-1)
|
||||
#define USB_RET_NAK (-2)
|
||||
#define USB_RET_STALL (-3)
|
||||
#define USB_RET_BABBLE (-4)
|
||||
#define USB_RET_IOERROR (-5)
|
||||
#define USB_RET_ASYNC (-6)
|
||||
#define USB_RET_ADD_TO_QUEUE (-7)
|
||||
#define USB_RET_SUCCESS (0)
|
||||
#define USB_RET_NODEV (-1)
|
||||
#define USB_RET_NAK (-2)
|
||||
#define USB_RET_STALL (-3)
|
||||
#define USB_RET_BABBLE (-4)
|
||||
#define USB_RET_IOERROR (-5)
|
||||
#define USB_RET_ASYNC (-6)
|
||||
#define USB_RET_ADD_TO_QUEUE (-7)
|
||||
#define USB_RET_REMOVE_FROM_QUEUE (-8)
|
||||
|
||||
#define USB_SPEED_LOW 0
|
||||
#define USB_SPEED_FULL 1
|
||||
#define USB_SPEED_HIGH 2
|
||||
#define USB_SPEED_LOW 0
|
||||
#define USB_SPEED_FULL 1
|
||||
#define USB_SPEED_HIGH 2
|
||||
|
||||
#define USB_SPEED_MASK_LOW (1 << USB_SPEED_LOW)
|
||||
#define USB_SPEED_MASK_FULL (1 << USB_SPEED_FULL)
|
||||
#define USB_SPEED_MASK_LOW (1 << USB_SPEED_LOW)
|
||||
#define USB_SPEED_MASK_FULL (1 << USB_SPEED_FULL)
|
||||
|
||||
#define USB_STATE_NOTATTACHED 0
|
||||
#define USB_STATE_ATTACHED 1
|
||||
#define USB_STATE_ATTACHED 1
|
||||
//#define USB_STATE_POWERED 2
|
||||
#define USB_STATE_DEFAULT 3
|
||||
#define USB_STATE_DEFAULT 3
|
||||
//#define USB_STATE_ADDRESS 4
|
||||
//#define USB_STATE_CONFIGURED 5
|
||||
#define USB_STATE_SUSPENDED 6
|
||||
#define USB_STATE_SUSPENDED 6
|
||||
|
||||
#define USB_CLASS_RESERVED 0
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PHYSICAL 5
|
||||
#define USB_CLASS_STILL_IMAGE 6
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_CDC_DATA 0x0a
|
||||
#define USB_CLASS_CSCID 0x0b
|
||||
#define USB_CLASS_CONTENT_SEC 0x0d
|
||||
#define USB_CLASS_APP_SPEC 0xfe
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
#define USB_CLASS_RESERVED 0
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PHYSICAL 5
|
||||
#define USB_CLASS_STILL_IMAGE 6
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_CDC_DATA 0x0a
|
||||
#define USB_CLASS_CSCID 0x0b
|
||||
#define USB_CLASS_CONTENT_SEC 0x0d
|
||||
#define USB_CLASS_APP_SPEC 0xfe
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
|
||||
#define USB_DIR_OUT 0
|
||||
#define USB_DIR_IN 0x80
|
||||
#define USB_DIR_OUT 0
|
||||
#define USB_DIR_IN 0x80
|
||||
|
||||
#define USB_TYPE_MASK (0x03 << 5)
|
||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
||||
#define USB_TYPE_MASK (0x03 << 5)
|
||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
||||
|
||||
#define USB_RECIP_MASK 0x1f
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
#define USB_RECIP_MASK 0x1f
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
|
||||
#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) //0x8000
|
||||
#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) // 0x0000
|
||||
#define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) // 0xC000
|
||||
#define DeviceRequest ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8) //0x8000
|
||||
#define DeviceOutRequest ((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8) // 0x0000
|
||||
#define VendorDeviceRequest ((USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) << 8) // 0xC000
|
||||
#define VendorDeviceOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) //0x4000
|
||||
((USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) << 8) //0x4000
|
||||
#define InterfaceRequest \
|
||||
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) // 0x8100
|
||||
((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8) // 0x8100
|
||||
#define InterfaceOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) //0x0100
|
||||
#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) //0x8200
|
||||
((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8) //0x0100
|
||||
#define EndpointRequest ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) << 8) //0x8200
|
||||
#define EndpointOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) //0x0200
|
||||
((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) << 8) //0x0200
|
||||
|
||||
#define ClassInterfaceRequest \
|
||||
((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) //0xA100
|
||||
((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) //0xA100
|
||||
#define ClassInterfaceOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) //0x2100
|
||||
((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) //0x2100
|
||||
|
||||
#define ClassEndpointRequest \
|
||||
((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT)<<8) //0xA200
|
||||
((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) << 8) //0xA200
|
||||
#define ClassEndpointOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_ENDPOINT)<<8) //0x2200
|
||||
((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) << 8) //0x2200
|
||||
|
||||
#define VendorInterfaceRequest \
|
||||
((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
|
||||
((USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE) << 8)
|
||||
#define VendorInterfaceOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
|
||||
((USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE) << 8)
|
||||
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_DEVICE_SELF_POWERED 0
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1
|
||||
#define USB_DEVICE_SELF_POWERED 0
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1
|
||||
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
#define USB_DT_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DT_OTHER_SPEED_CONFIG 0x07
|
||||
#define USB_DT_DEBUG 0x0A
|
||||
#define USB_DT_INTERFACE_ASSOC 0x0B
|
||||
#define USB_DT_BOS 0x0F
|
||||
#define USB_DT_DEVICE_CAPABILITY 0x10
|
||||
#define USB_DT_HID 0x21
|
||||
#define USB_DT_REPORT 0x22
|
||||
#define USB_DT_PHYSICAL 0x23
|
||||
#define USB_DT_CS_INTERFACE 0x24
|
||||
#define USB_DT_CS_ENDPOINT 0x25
|
||||
#define USB_DT_ENDPOINT_COMPANION 0x30
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
#define USB_DT_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DT_OTHER_SPEED_CONFIG 0x07
|
||||
#define USB_DT_DEBUG 0x0A
|
||||
#define USB_DT_INTERFACE_ASSOC 0x0B
|
||||
#define USB_DT_BOS 0x0F
|
||||
#define USB_DT_DEVICE_CAPABILITY 0x10
|
||||
#define USB_DT_HID 0x21
|
||||
#define USB_DT_REPORT 0x22
|
||||
#define USB_DT_PHYSICAL 0x23
|
||||
#define USB_DT_CS_INTERFACE 0x24
|
||||
#define USB_DT_CS_ENDPOINT 0x25
|
||||
#define USB_DT_ENDPOINT_COMPANION 0x30
|
||||
|
||||
#define USB_DEV_CAP_WIRELESS 0x01
|
||||
#define USB_DEV_CAP_USB2_EXT 0x02
|
||||
#define USB_DEV_CAP_SUPERSPEED 0x03
|
||||
#define USB_DEV_CAP_WIRELESS 0x01
|
||||
#define USB_DEV_CAP_USB2_EXT 0x02
|
||||
#define USB_DEV_CAP_SUPERSPEED 0x03
|
||||
|
||||
#define USB_CFG_ATT_ONE (1 << 7) /* should always be set */
|
||||
#define USB_CFG_ATT_SELFPOWER (1 << 6)
|
||||
#define USB_CFG_ATT_WAKEUP (1 << 5)
|
||||
#define USB_CFG_ATT_BATTERY (1 << 4)
|
||||
#define USB_CFG_ATT_ONE (1 << 7) /* should always be set */
|
||||
#define USB_CFG_ATT_SELFPOWER (1 << 6)
|
||||
#define USB_CFG_ATT_WAKEUP (1 << 5)
|
||||
#define USB_CFG_ATT_BATTERY (1 << 4)
|
||||
|
||||
#define USB_ENDPOINT_XFER_CONTROL 0
|
||||
#define USB_ENDPOINT_XFER_ISOC 1
|
||||
#define USB_ENDPOINT_XFER_BULK 2
|
||||
#define USB_ENDPOINT_XFER_INT 3
|
||||
#define USB_ENDPOINT_XFER_INVALID 255
|
||||
#define USB_ENDPOINT_XFER_CONTROL 0
|
||||
#define USB_ENDPOINT_XFER_ISOC 1
|
||||
#define USB_ENDPOINT_XFER_BULK 2
|
||||
#define USB_ENDPOINT_XFER_INT 3
|
||||
#define USB_ENDPOINT_XFER_INVALID 255
|
||||
|
||||
#define USB_INTERFACE_INVALID 255
|
||||
#define USB_INTERFACE_INVALID 255
|
||||
|
||||
/* HID interface requests */
|
||||
#define GET_REPORT 0xa101
|
||||
#define GET_IDLE 0xa102
|
||||
#define GET_REPORT 0xa101
|
||||
#define GET_IDLE 0xa102
|
||||
#define GET_PROTOCOL 0xa103
|
||||
#define SET_REPORT 0x2109
|
||||
#define SET_IDLE 0x210a
|
||||
#define SET_REPORT 0x2109
|
||||
#define SET_IDLE 0x210a
|
||||
#define SET_PROTOCOL 0x210b
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE 18
|
||||
#define USB_DEVICE_DESC_SIZE 18
|
||||
#define USB_CONFIGURATION_DESC_SIZE 9
|
||||
#define USB_INTERFACE_DESC_SIZE 9
|
||||
#define USB_ENDPOINT_DESC_SIZE 7
|
||||
#define USB_INTERFACE_DESC_SIZE 9
|
||||
#define USB_ENDPOINT_DESC_SIZE 7
|
||||
|
||||
#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
||||
#define B3VAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF),(((x) >> 16) & 0xFF)
|
||||
#define WBVAL(x) ((x)&0xFF), (((x) >> 8) & 0xFF)
|
||||
#define B3VAL(x) ((x)&0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF)
|
||||
|
||||
/* bmRequestType.Dir */
|
||||
#define REQUEST_HOST_TO_DEVICE 0
|
||||
#define REQUEST_DEVICE_TO_HOST 1
|
||||
#define REQUEST_HOST_TO_DEVICE 0
|
||||
#define REQUEST_DEVICE_TO_HOST 1
|
||||
|
||||
/* bmRequestType.Type */
|
||||
#define REQUEST_STANDARD 0
|
||||
#define REQUEST_CLASS 1
|
||||
#define REQUEST_VENDOR 2
|
||||
#define REQUEST_RESERVED 3
|
||||
#define REQUEST_STANDARD 0
|
||||
#define REQUEST_CLASS 1
|
||||
#define REQUEST_VENDOR 2
|
||||
#define REQUEST_RESERVED 3
|
||||
|
||||
/* bmRequestType.Recipient */
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
|
||||
/* USB Standard Request Codes */
|
||||
#define USB_REQUEST_GET_STATUS 0
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1
|
||||
#define USB_REQUEST_SET_FEATURE 3
|
||||
#define USB_REQUEST_SET_ADDRESS 5
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9
|
||||
#define USB_REQUEST_GET_INTERFACE 10
|
||||
#define USB_REQUEST_SET_INTERFACE 11
|
||||
#define USB_REQUEST_SYNC_FRAME 12
|
||||
#define USB_REQUEST_GET_STATUS 0
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1
|
||||
#define USB_REQUEST_SET_FEATURE 3
|
||||
#define USB_REQUEST_SET_ADDRESS 5
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9
|
||||
#define USB_REQUEST_GET_INTERFACE 10
|
||||
#define USB_REQUEST_SET_INTERFACE 11
|
||||
#define USB_REQUEST_SYNC_FRAME 12
|
||||
|
||||
/* USB GET_STATUS Bit Values */
|
||||
#define USB_GETSTATUS_SELF_POWERED 0x01
|
||||
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
|
||||
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
|
||||
#define USB_GETSTATUS_SELF_POWERED 0x01
|
||||
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
|
||||
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
|
||||
|
||||
/* USB Standard Feature selectors */
|
||||
#define USB_FEATURE_ENDPOINT_STALL 0
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||
#define USB_FEATURE_ENDPOINT_STALL 0
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||
|
||||
/* USB Descriptor Types */
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
||||
#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
||||
#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
|
||||
#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
|
||||
#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
|
||||
#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
|
||||
|
||||
/* bmAttributes in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWERED_MASK 0xC0
|
||||
#define USB_CONFIG_BUS_POWERED 0x80
|
||||
#define USB_CONFIG_SELF_POWERED 0x40
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
||||
#define USB_CONFIG_POWERED_MASK 0xC0
|
||||
#define USB_CONFIG_BUS_POWERED 0x80
|
||||
#define USB_CONFIG_SELF_POWERED 0x40
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
||||
|
||||
/* bMaxPower in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
|
||||
#define USB_CONFIG_POWER_MA(mA) ((mA) / 2)
|
||||
|
||||
/* bEndpointAddress in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
||||
|
||||
/* bmAttributes in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
||||
#define USB_ENDPOINT_SYNC_MASK 0x0C
|
||||
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
|
||||
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
|
||||
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
|
||||
#define USB_ENDPOINT_USAGE_MASK 0x30
|
||||
#define USB_ENDPOINT_USAGE_DATA 0x00
|
||||
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
|
||||
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
|
||||
#define USB_ENDPOINT_USAGE_RESERVED 0x30
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
||||
#define USB_ENDPOINT_SYNC_MASK 0x0C
|
||||
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
|
||||
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
|
||||
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
|
||||
#define USB_ENDPOINT_USAGE_MASK 0x30
|
||||
#define USB_ENDPOINT_USAGE_DATA 0x00
|
||||
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
|
||||
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
|
||||
#define USB_ENDPOINT_USAGE_RESERVED 0x30
|
||||
|
||||
typedef struct USBBus USBBus;
|
||||
typedef struct USBBusOps USBBusOps;
|
||||
|
@ -281,323 +281,344 @@ typedef struct USBDescOther USBDescOther;
|
|||
typedef struct USBDescString USBDescString;
|
||||
typedef struct USBDescMSOS USBDescMSOS;
|
||||
|
||||
struct USBDescString {
|
||||
uint8_t index;
|
||||
char *str;
|
||||
QLIST_ENTRY(USBDescString) next;
|
||||
struct USBDescString
|
||||
{
|
||||
uint8_t index;
|
||||
char* str;
|
||||
QLIST_ENTRY(USBDescString)
|
||||
next;
|
||||
};
|
||||
|
||||
#define USB_MAX_ENDPOINTS 15
|
||||
#define USB_MAX_ENDPOINTS 15
|
||||
#define USB_MAX_INTERFACES 16
|
||||
|
||||
struct USBEndpoint {
|
||||
uint8_t nr;
|
||||
uint8_t pid;
|
||||
uint8_t type;
|
||||
uint8_t ifnum;
|
||||
int max_packet_size;
|
||||
int max_streams;
|
||||
bool pipeline;
|
||||
bool halted;
|
||||
USBDevice *dev;
|
||||
QTAILQ_HEAD(, USBPacket) queue;
|
||||
struct USBEndpoint
|
||||
{
|
||||
uint8_t nr;
|
||||
uint8_t pid;
|
||||
uint8_t type;
|
||||
uint8_t ifnum;
|
||||
int max_packet_size;
|
||||
int max_streams;
|
||||
bool pipeline;
|
||||
bool halted;
|
||||
USBDevice* dev;
|
||||
QTAILQ_HEAD(, USBPacket)
|
||||
queue;
|
||||
};
|
||||
|
||||
enum USBDeviceFlags {
|
||||
USB_DEV_FLAG_FULL_PATH,
|
||||
USB_DEV_FLAG_IS_HOST,
|
||||
USB_DEV_FLAG_MSOS_DESC_ENABLE,
|
||||
USB_DEV_FLAG_MSOS_DESC_IN_USE,
|
||||
enum USBDeviceFlags
|
||||
{
|
||||
USB_DEV_FLAG_FULL_PATH,
|
||||
USB_DEV_FLAG_IS_HOST,
|
||||
USB_DEV_FLAG_MSOS_DESC_ENABLE,
|
||||
USB_DEV_FLAG_MSOS_DESC_IN_USE,
|
||||
};
|
||||
|
||||
typedef void (*USBDeviceRealize)(USBDevice *dev/*, Error **errp*/);
|
||||
typedef void (*USBDeviceUnrealize)(USBDevice *dev/*, Error **errp*/);
|
||||
typedef void (*USBDeviceRealize)(USBDevice* dev /*, Error **errp*/);
|
||||
typedef void (*USBDeviceUnrealize)(USBDevice* dev /*, Error **errp*/);
|
||||
|
||||
typedef struct USBDeviceClass {
|
||||
//DeviceClass parent_class;
|
||||
typedef struct USBDeviceClass
|
||||
{
|
||||
//DeviceClass parent_class;
|
||||
|
||||
USBDeviceRealize realize;
|
||||
USBDeviceUnrealize unrealize;
|
||||
USBDeviceRealize realize;
|
||||
USBDeviceUnrealize unrealize;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Walk (enabled) downstream ports, check for a matching device.
|
||||
* Only hubs implement this.
|
||||
*/
|
||||
USBDevice *(*find_device)(USBDevice *dev, uint8_t addr);
|
||||
USBDevice* (*find_device)(USBDevice* dev, uint8_t addr);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Called when a packet is canceled.
|
||||
*/
|
||||
void (*cancel_packet)(USBDevice *dev, USBPacket *p);
|
||||
void (*cancel_packet)(USBDevice* dev, USBPacket* p);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Attach the device
|
||||
*/
|
||||
void (*handle_attach)(USBDevice *dev);
|
||||
void (*handle_attach)(USBDevice* dev);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Reset the device
|
||||
*/
|
||||
void (*handle_reset)(USBDevice *dev);
|
||||
void (*handle_reset)(USBDevice* dev);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Process control request.
|
||||
* Called from handle_packet().
|
||||
*
|
||||
* Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
|
||||
* then the number of bytes transferred is stored in p->actual_length
|
||||
*/
|
||||
void (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value,
|
||||
int index, int length, uint8_t *data);
|
||||
void (*handle_control)(USBDevice* dev, USBPacket* p, int request, int value,
|
||||
int index, int length, uint8_t* data);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Process data transfers (both BULK and ISOC).
|
||||
* Called from handle_packet().
|
||||
*
|
||||
* Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
|
||||
* then the number of bytes transferred is stored in p->actual_length
|
||||
*/
|
||||
void (*handle_data)(USBDevice *dev, USBPacket *p);
|
||||
void (*handle_data)(USBDevice* dev, USBPacket* p);
|
||||
|
||||
void (*set_interface)(USBDevice *dev, int intf,
|
||||
int alt_old, int alt_new);
|
||||
void (*set_interface)(USBDevice* dev, int intf,
|
||||
int alt_old, int alt_new);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Called when the hcd is done queuing packets for an endpoint, only
|
||||
* necessary for devices which can return USB_RET_ADD_TO_QUEUE.
|
||||
*/
|
||||
void (*flush_ep_queue)(USBDevice *dev, USBEndpoint *ep);
|
||||
void (*flush_ep_queue)(USBDevice* dev, USBEndpoint* ep);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Called by the hcd to let the device know the queue for an endpoint
|
||||
* has been unlinked / stopped. Optional may be NULL.
|
||||
*/
|
||||
void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
|
||||
void (*ep_stopped)(USBDevice* dev, USBEndpoint* ep);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Called by the hcd to alloc / free streams on a bulk endpoint.
|
||||
* Optional may be NULL.
|
||||
*/
|
||||
int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps,
|
||||
int streams);
|
||||
void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps);
|
||||
|
||||
int (*open)(USBDevice *dev);
|
||||
void (*close)(USBDevice *dev);
|
||||
int (*alloc_streams)(USBDevice* dev, USBEndpoint** eps, int nr_eps,
|
||||
int streams);
|
||||
void (*free_streams)(USBDevice* dev, USBEndpoint** eps, int nr_eps);
|
||||
|
||||
const char *product_desc;
|
||||
const USBDesc *usb_desc;
|
||||
bool attached_settable;
|
||||
int (*open)(USBDevice* dev);
|
||||
void (*close)(USBDevice* dev);
|
||||
|
||||
const char* product_desc;
|
||||
const USBDesc* usb_desc;
|
||||
bool attached_settable;
|
||||
} USBDeviceClass;
|
||||
|
||||
/* definition of a USB device */
|
||||
struct USBDevice {
|
||||
USBDeviceClass klass;
|
||||
USBPort *port;
|
||||
USBBus *bus;
|
||||
void *opaque;
|
||||
uint32_t flags;
|
||||
struct USBDevice
|
||||
{
|
||||
USBDeviceClass klass;
|
||||
USBPort* port;
|
||||
USBBus* bus;
|
||||
void* opaque;
|
||||
uint32_t flags;
|
||||
|
||||
/* Actual connected speed */
|
||||
int speed;
|
||||
/* Supported speeds, not in info because it may be variable (hostdevs) */
|
||||
int speedmask;
|
||||
uint8_t addr;
|
||||
char product_desc[32];
|
||||
int auto_attach;
|
||||
bool attached;
|
||||
/* Actual connected speed */
|
||||
int speed;
|
||||
/* Supported speeds, not in info because it may be variable (hostdevs) */
|
||||
int speedmask;
|
||||
uint8_t addr;
|
||||
char product_desc[32];
|
||||
int auto_attach;
|
||||
bool attached;
|
||||
|
||||
int32_t state;
|
||||
uint8_t setup_buf[8];
|
||||
uint8_t data_buf[4096];
|
||||
int32_t remote_wakeup;
|
||||
int32_t setup_state;
|
||||
int32_t setup_len;
|
||||
int32_t setup_index;
|
||||
int32_t state;
|
||||
uint8_t setup_buf[8];
|
||||
uint8_t data_buf[4096];
|
||||
int32_t remote_wakeup;
|
||||
int32_t setup_state;
|
||||
int32_t setup_len;
|
||||
int32_t setup_index;
|
||||
|
||||
USBEndpoint ep_ctl;
|
||||
USBEndpoint ep_in[USB_MAX_ENDPOINTS];
|
||||
USBEndpoint ep_out[USB_MAX_ENDPOINTS];
|
||||
USBEndpoint ep_ctl;
|
||||
USBEndpoint ep_in[USB_MAX_ENDPOINTS];
|
||||
USBEndpoint ep_out[USB_MAX_ENDPOINTS];
|
||||
|
||||
const USBDesc *usb_desc; /* Overrides class usb_desc if not NULL */
|
||||
const USBDescDevice *device;
|
||||
const USBDesc* usb_desc; /* Overrides class usb_desc if not NULL */
|
||||
const USBDescDevice* device;
|
||||
|
||||
int configuration;
|
||||
int ninterfaces;
|
||||
int altsetting[USB_MAX_INTERFACES];
|
||||
const USBDescConfig *config;
|
||||
const USBDescIface *ifaces[USB_MAX_INTERFACES];
|
||||
int configuration;
|
||||
int ninterfaces;
|
||||
int altsetting[USB_MAX_INTERFACES];
|
||||
const USBDescConfig* config;
|
||||
const USBDescIface* ifaces[USB_MAX_INTERFACES];
|
||||
};
|
||||
|
||||
typedef struct USBPortOps {
|
||||
void (*attach)(USBPort *port);
|
||||
void (*detach)(USBPort *port);
|
||||
/*
|
||||
typedef struct USBPortOps
|
||||
{
|
||||
void (*attach)(USBPort* port);
|
||||
void (*detach)(USBPort* port);
|
||||
/*
|
||||
* This gets called when a device downstream from the device attached to
|
||||
* the port (iow attached through a hub) gets detached.
|
||||
*/
|
||||
//void (*child_detach)(USBPort *port, USBDevice *child);
|
||||
void (*wakeup)(USBPort *port);
|
||||
/*
|
||||
//void (*child_detach)(USBPort *port, USBDevice *child);
|
||||
void (*wakeup)(USBPort* port);
|
||||
/*
|
||||
* Note that port->dev will be different then the device from which
|
||||
* the packet originated when a hub is involved.
|
||||
*/
|
||||
void (*complete)(USBPort *port, USBPacket *p);
|
||||
void (*complete)(USBPort* port, USBPacket* p);
|
||||
} USBPortOps;
|
||||
|
||||
/* USB port on which a device can be connected */
|
||||
struct USBPort {
|
||||
USBDevice *dev;
|
||||
int speedmask;
|
||||
USBPortOps *ops;
|
||||
void *opaque;
|
||||
int index; /* internal port index, may be used with the opaque */
|
||||
//QTAILQ_ENTRY(USBPort) next; /* Used internally by qemu. */
|
||||
struct USBPort
|
||||
{
|
||||
USBDevice* dev;
|
||||
int speedmask;
|
||||
USBPortOps* ops;
|
||||
void* opaque;
|
||||
int index; /* internal port index, may be used with the opaque */
|
||||
//QTAILQ_ENTRY(USBPort) next; /* Used internally by qemu. */
|
||||
};
|
||||
|
||||
typedef void USBCallback(USBPacket * packet, void *opaque);
|
||||
typedef void USBCallback(USBPacket* packet, void* opaque);
|
||||
|
||||
typedef enum USBPacketState {
|
||||
USB_PACKET_UNDEFINED = 0,
|
||||
USB_PACKET_SETUP,
|
||||
USB_PACKET_QUEUED,
|
||||
USB_PACKET_ASYNC,
|
||||
USB_PACKET_COMPLETE,
|
||||
USB_PACKET_CANCELED,
|
||||
typedef enum USBPacketState
|
||||
{
|
||||
USB_PACKET_UNDEFINED = 0,
|
||||
USB_PACKET_SETUP,
|
||||
USB_PACKET_QUEUED,
|
||||
USB_PACKET_ASYNC,
|
||||
USB_PACKET_COMPLETE,
|
||||
USB_PACKET_CANCELED,
|
||||
} USBPacketState;
|
||||
|
||||
/* Structure used to hold information about an active USB packet. */
|
||||
struct USBPacket {
|
||||
/* Data fields for use by the driver. */
|
||||
int pid;
|
||||
uint64_t id;
|
||||
USBEndpoint *ep;
|
||||
unsigned int stream;
|
||||
QEMUIOVector iov;
|
||||
uint64_t parameter; /* control transfers */
|
||||
bool short_not_ok;
|
||||
bool int_req;
|
||||
int status; /* USB_RET_* status code */
|
||||
int actual_length; /* Number of bytes actually transferred */
|
||||
/* Internal use by the USB layer. */
|
||||
USBPacketState state;
|
||||
USBCombinedPacket *combined;
|
||||
QTAILQ_ENTRY(USBPacket) queue;
|
||||
QTAILQ_ENTRY(USBPacket) combined_entry;
|
||||
struct USBPacket
|
||||
{
|
||||
/* Data fields for use by the driver. */
|
||||
int pid;
|
||||
uint64_t id;
|
||||
USBEndpoint* ep;
|
||||
unsigned int stream;
|
||||
QEMUIOVector iov;
|
||||
uint64_t parameter; /* control transfers */
|
||||
bool short_not_ok;
|
||||
bool int_req;
|
||||
int status; /* USB_RET_* status code */
|
||||
int actual_length; /* Number of bytes actually transferred */
|
||||
/* Internal use by the USB layer. */
|
||||
USBPacketState state;
|
||||
USBCombinedPacket* combined;
|
||||
QTAILQ_ENTRY(USBPacket)
|
||||
queue;
|
||||
QTAILQ_ENTRY(USBPacket)
|
||||
combined_entry;
|
||||
};
|
||||
|
||||
struct USBCombinedPacket {
|
||||
USBPacket *first;
|
||||
QTAILQ_HEAD(packets_head, USBPacket) packets;
|
||||
QEMUIOVector iov;
|
||||
struct USBCombinedPacket
|
||||
{
|
||||
USBPacket* first;
|
||||
QTAILQ_HEAD(packets_head, USBPacket)
|
||||
packets;
|
||||
QEMUIOVector iov;
|
||||
};
|
||||
|
||||
void usb_packet_init(USBPacket *p);
|
||||
void usb_packet_set_state(USBPacket *p, USBPacketState state);
|
||||
void usb_packet_check_state(USBPacket *p, USBPacketState expected);
|
||||
void usb_packet_setup(USBPacket *p, int pid,
|
||||
USBEndpoint *ep, unsigned int stream,
|
||||
uint64_t id, bool short_not_ok, bool int_req);
|
||||
void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
|
||||
void usb_packet_init(USBPacket* p);
|
||||
void usb_packet_set_state(USBPacket* p, USBPacketState state);
|
||||
void usb_packet_check_state(USBPacket* p, USBPacketState expected);
|
||||
void usb_packet_setup(USBPacket* p, int pid,
|
||||
USBEndpoint* ep, unsigned int stream,
|
||||
uint64_t id, bool short_not_ok, bool int_req);
|
||||
void usb_packet_addbuf(USBPacket* p, void* ptr, size_t len);
|
||||
//int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
|
||||
//void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
|
||||
void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes);
|
||||
void usb_packet_skip(USBPacket *p, size_t bytes);
|
||||
size_t usb_packet_size(USBPacket *p);
|
||||
void usb_packet_cleanup(USBPacket *p);
|
||||
void usb_packet_copy(USBPacket* p, void* ptr, size_t bytes);
|
||||
void usb_packet_skip(USBPacket* p, size_t bytes);
|
||||
size_t usb_packet_size(USBPacket* p);
|
||||
void usb_packet_cleanup(USBPacket* p);
|
||||
|
||||
static inline bool usb_packet_is_inflight(USBPacket *p)
|
||||
static inline bool usb_packet_is_inflight(USBPacket* p)
|
||||
{
|
||||
return (p->state == USB_PACKET_QUEUED ||
|
||||
p->state == USB_PACKET_ASYNC);
|
||||
return (p->state == USB_PACKET_QUEUED ||
|
||||
p->state == USB_PACKET_ASYNC);
|
||||
}
|
||||
|
||||
struct USBBus {
|
||||
//BusState qbus;
|
||||
USBBusOps *ops;
|
||||
int busnr;
|
||||
int nfree;
|
||||
int nused;
|
||||
QTAILQ_HEAD(, USBPort) free;
|
||||
QTAILQ_HEAD(, USBPort) used;
|
||||
QTAILQ_ENTRY(USBBus) next;
|
||||
struct USBBus
|
||||
{
|
||||
//BusState qbus;
|
||||
USBBusOps* ops;
|
||||
int busnr;
|
||||
int nfree;
|
||||
int nused;
|
||||
QTAILQ_HEAD(, USBPort)
|
||||
free;
|
||||
QTAILQ_HEAD(, USBPort)
|
||||
used;
|
||||
QTAILQ_ENTRY(USBBus)
|
||||
next;
|
||||
};
|
||||
|
||||
struct USBBusOps {
|
||||
void (*register_companion)(USBBus *bus, USBPort *ports[],
|
||||
uint32_t portcount, uint32_t firstport/*,
|
||||
Error **errp*/);
|
||||
void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
|
||||
struct USBBusOps
|
||||
{
|
||||
void (*register_companion)(USBBus* bus, USBPort* ports[],
|
||||
uint32_t portcount, uint32_t firstport /*,
|
||||
Error **errp*/
|
||||
);
|
||||
void (*wakeup_endpoint)(USBBus* bus, USBEndpoint* ep, unsigned int stream);
|
||||
};
|
||||
|
||||
USBDevice *usb_find_device(USBPort *port, uint8_t addr);
|
||||
USBDevice* usb_find_device(USBPort* port, uint8_t addr);
|
||||
|
||||
void usb_handle_packet(USBDevice *dev, USBPacket *p);
|
||||
void usb_packet_complete(USBDevice *dev, USBPacket *p);
|
||||
void usb_packet_complete_one(USBDevice *dev, USBPacket *p);
|
||||
void usb_cancel_packet(USBPacket * p);
|
||||
void usb_handle_packet(USBDevice* dev, USBPacket* p);
|
||||
void usb_packet_complete(USBDevice* dev, USBPacket* p);
|
||||
void usb_packet_complete_one(USBDevice* dev, USBPacket* p);
|
||||
void usb_cancel_packet(USBPacket* p);
|
||||
|
||||
void usb_ep_init(USBDevice *dev);
|
||||
void usb_ep_reset(USBDevice *dev);
|
||||
void usb_ep_dump(USBDevice *dev);
|
||||
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
|
||||
uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
|
||||
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
|
||||
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
|
||||
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
|
||||
uint16_t raw);
|
||||
void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw);
|
||||
void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted);
|
||||
USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
|
||||
uint64_t id);
|
||||
void usb_ep_init(USBDevice* dev);
|
||||
void usb_ep_reset(USBDevice* dev);
|
||||
void usb_ep_dump(USBDevice* dev);
|
||||
struct USBEndpoint* usb_ep_get(USBDevice* dev, int pid, int ep);
|
||||
uint8_t usb_ep_get_type(USBDevice* dev, int pid, int ep);
|
||||
void usb_ep_set_type(USBDevice* dev, int pid, int ep, uint8_t type);
|
||||
void usb_ep_set_ifnum(USBDevice* dev, int pid, int ep, uint8_t ifnum);
|
||||
void usb_ep_set_max_packet_size(USBDevice* dev, int pid, int ep,
|
||||
uint16_t raw);
|
||||
void usb_ep_set_max_streams(USBDevice* dev, int pid, int ep, uint8_t raw);
|
||||
void usb_ep_set_halted(USBDevice* dev, int pid, int ep, bool halted);
|
||||
USBPacket* usb_ep_find_packet_by_id(USBDevice* dev, int pid, int ep,
|
||||
uint64_t id);
|
||||
|
||||
void usb_ep_combine_input_packets(USBEndpoint *ep);
|
||||
void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p);
|
||||
void usb_combined_packet_cancel(USBDevice *dev, USBPacket *p);
|
||||
void usb_ep_combine_input_packets(USBEndpoint* ep);
|
||||
void usb_combined_input_packet_complete(USBDevice* dev, USBPacket* p);
|
||||
void usb_combined_packet_cancel(USBDevice* dev, USBPacket* p);
|
||||
|
||||
void usb_pick_speed(USBPort *port);
|
||||
void usb_attach(USBPort *port);
|
||||
void usb_detach(USBPort *port);
|
||||
void usb_port_reset(USBPort *port);
|
||||
void usb_device_reset(USBDevice *dev);
|
||||
void usb_wakeup(USBEndpoint *ep, unsigned int stream);
|
||||
void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
|
||||
void usb_pick_speed(USBPort* port);
|
||||
void usb_attach(USBPort* port);
|
||||
void usb_detach(USBPort* port);
|
||||
void usb_port_reset(USBPort* port);
|
||||
void usb_device_reset(USBDevice* dev);
|
||||
void usb_wakeup(USBEndpoint* ep, unsigned int stream);
|
||||
void usb_generic_async_ctrl_complete(USBDevice* s, USBPacket* p);
|
||||
|
||||
|
||||
int usb_generic_handle_packet(USBDevice *s, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t *data, int len);
|
||||
void usb_reattach(USBPort *port);
|
||||
void usb_send_msg(USBDevice *dev, int msg);
|
||||
int usb_generic_handle_packet(USBDevice* s, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t* data, int len);
|
||||
void usb_reattach(USBPort* port);
|
||||
void usb_send_msg(USBDevice* dev, int msg);
|
||||
|
||||
|
||||
/* usb hub */
|
||||
USBDevice *usb_hub_init(int nb_ports);
|
||||
USBDevice* usb_hub_init(int nb_ports);
|
||||
|
||||
USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr);
|
||||
USBDevice* usb_device_find_device(USBDevice* dev, uint8_t addr);
|
||||
|
||||
void usb_device_cancel_packet(USBDevice *dev, USBPacket *p);
|
||||
void usb_device_cancel_packet(USBDevice* dev, USBPacket* p);
|
||||
|
||||
void usb_device_handle_attach(USBDevice *dev);
|
||||
void usb_device_handle_attach(USBDevice* dev);
|
||||
|
||||
void usb_device_handle_reset(USBDevice *dev);
|
||||
void usb_device_handle_reset(USBDevice* dev);
|
||||
|
||||
void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
|
||||
int val, int index, int length, uint8_t *data);
|
||||
void usb_device_handle_control(USBDevice* dev, USBPacket* p, int request,
|
||||
int val, int index, int length, uint8_t* data);
|
||||
|
||||
void usb_device_handle_data(USBDevice *dev, USBPacket *p);
|
||||
void usb_device_handle_data(USBDevice* dev, USBPacket* p);
|
||||
|
||||
void usb_device_set_interface(USBDevice *dev, int intf,
|
||||
int alt_old, int alt_new);
|
||||
void usb_device_set_interface(USBDevice* dev, int intf,
|
||||
int alt_old, int alt_new);
|
||||
|
||||
void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
|
||||
void usb_device_flush_ep_queue(USBDevice* dev, USBEndpoint* ep);
|
||||
|
||||
void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
|
||||
void usb_device_ep_stopped(USBDevice* dev, USBEndpoint* ep);
|
||||
|
||||
int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
|
||||
int streams);
|
||||
void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps);
|
||||
int usb_device_alloc_streams(USBDevice* dev, USBEndpoint** eps, int nr_eps,
|
||||
int streams);
|
||||
void usb_device_free_streams(USBDevice* dev, USBEndpoint** eps, int nr_eps);
|
||||
|
||||
const char *usb_device_get_product_desc(USBDevice *dev);
|
||||
const char* usb_device_get_product_desc(USBDevice* dev);
|
||||
|
||||
const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
|
||||
const USBDesc* usb_device_get_usb_desc(USBDevice* dev);
|
|
@ -27,58 +27,60 @@
|
|||
|
||||
#define MAX_PORTS 8
|
||||
|
||||
typedef struct USBHubPort {
|
||||
USBPort port;
|
||||
uint16_t wPortStatus;
|
||||
uint16_t wPortChange;
|
||||
typedef struct USBHubPort
|
||||
{
|
||||
USBPort port;
|
||||
uint16_t wPortStatus;
|
||||
uint16_t wPortChange;
|
||||
} USBHubPort;
|
||||
|
||||
typedef struct USBHubState {
|
||||
USBDevice dev;
|
||||
int nb_ports;
|
||||
USBHubPort ports[MAX_PORTS];
|
||||
typedef struct USBHubState
|
||||
{
|
||||
USBDevice dev;
|
||||
int nb_ports;
|
||||
USBHubPort ports[MAX_PORTS];
|
||||
} USBHubState;
|
||||
|
||||
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
|
||||
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
|
||||
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
|
||||
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
|
||||
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
|
||||
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
|
||||
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
|
||||
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
|
||||
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
|
||||
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
|
||||
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
|
||||
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
|
||||
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
|
||||
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
|
||||
|
||||
#define PORT_STAT_CONNECTION 0x0001
|
||||
#define PORT_STAT_ENABLE 0x0002
|
||||
#define PORT_STAT_SUSPEND 0x0004
|
||||
#define PORT_STAT_OVERCURRENT 0x0008
|
||||
#define PORT_STAT_RESET 0x0010
|
||||
#define PORT_STAT_POWER 0x0100
|
||||
#define PORT_STAT_LOW_SPEED 0x0200
|
||||
#define PORT_STAT_HIGH_SPEED 0x0400
|
||||
#define PORT_STAT_TEST 0x0800
|
||||
#define PORT_STAT_INDICATOR 0x1000
|
||||
#define PORT_STAT_CONNECTION 0x0001
|
||||
#define PORT_STAT_ENABLE 0x0002
|
||||
#define PORT_STAT_SUSPEND 0x0004
|
||||
#define PORT_STAT_OVERCURRENT 0x0008
|
||||
#define PORT_STAT_RESET 0x0010
|
||||
#define PORT_STAT_POWER 0x0100
|
||||
#define PORT_STAT_LOW_SPEED 0x0200
|
||||
#define PORT_STAT_HIGH_SPEED 0x0400
|
||||
#define PORT_STAT_TEST 0x0800
|
||||
#define PORT_STAT_INDICATOR 0x1000
|
||||
|
||||
#define PORT_STAT_C_CONNECTION 0x0001
|
||||
#define PORT_STAT_C_ENABLE 0x0002
|
||||
#define PORT_STAT_C_SUSPEND 0x0004
|
||||
#define PORT_STAT_C_OVERCURRENT 0x0008
|
||||
#define PORT_STAT_C_RESET 0x0010
|
||||
#define PORT_STAT_C_CONNECTION 0x0001
|
||||
#define PORT_STAT_C_ENABLE 0x0002
|
||||
#define PORT_STAT_C_SUSPEND 0x0004
|
||||
#define PORT_STAT_C_OVERCURRENT 0x0008
|
||||
#define PORT_STAT_C_RESET 0x0010
|
||||
|
||||
#define PORT_CONNECTION 0
|
||||
#define PORT_ENABLE 1
|
||||
#define PORT_SUSPEND 2
|
||||
#define PORT_OVERCURRENT 3
|
||||
#define PORT_RESET 4
|
||||
#define PORT_POWER 8
|
||||
#define PORT_LOWSPEED 9
|
||||
#define PORT_HIGHSPEED 10
|
||||
#define PORT_C_CONNECTION 16
|
||||
#define PORT_C_ENABLE 17
|
||||
#define PORT_C_SUSPEND 18
|
||||
#define PORT_C_OVERCURRENT 19
|
||||
#define PORT_C_RESET 20
|
||||
#define PORT_TEST 21
|
||||
#define PORT_INDICATOR 22
|
||||
#define PORT_CONNECTION 0
|
||||
#define PORT_ENABLE 1
|
||||
#define PORT_SUSPEND 2
|
||||
#define PORT_OVERCURRENT 3
|
||||
#define PORT_RESET 4
|
||||
#define PORT_POWER 8
|
||||
#define PORT_LOWSPEED 9
|
||||
#define PORT_HIGHSPEED 10
|
||||
#define PORT_C_CONNECTION 16
|
||||
#define PORT_C_ENABLE 17
|
||||
#define PORT_C_SUSPEND 18
|
||||
#define PORT_C_OVERCURRENT 19
|
||||
#define PORT_C_RESET 20
|
||||
#define PORT_TEST 21
|
||||
#define PORT_INDICATOR 22
|
||||
|
||||
/* same as Linux kernel root hubs */
|
||||
|
||||
|
@ -87,19 +89,19 @@ static const uint8_t qemu_hub_dev_descriptor[] = {
|
|||
0x01, /* u8 bDescriptorType; Device */
|
||||
0x10, 0x01, /* u16 bcdUSB; v1.1 */
|
||||
|
||||
0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
|
||||
0x00, /* u8 bDeviceSubClass; */
|
||||
0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
|
||||
0x08, /* u8 bMaxPacketSize0; 8 Bytes */
|
||||
0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
|
||||
0x00, /* u8 bDeviceSubClass; */
|
||||
0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
|
||||
0x08, /* u8 bMaxPacketSize0; 8 Bytes */
|
||||
|
||||
0x00, 0x00, /* u16 idVendor; */
|
||||
0x00, 0x00, /* u16 idProduct; */
|
||||
0x00, 0x00, /* u16 idProduct; */
|
||||
0x01, 0x01, /* u16 bcdDevice */
|
||||
|
||||
0x03, /* u8 iManufacturer; */
|
||||
0x02, /* u8 iProduct; */
|
||||
0x01, /* u8 iSerialNumber; */
|
||||
0x01 /* u8 bNumConfigurations; */
|
||||
0x03, /* u8 iManufacturer; */
|
||||
0x02, /* u8 iProduct; */
|
||||
0x01, /* u8 iSerialNumber; */
|
||||
0x01 /* u8 bNumConfigurations; */
|
||||
};
|
||||
|
||||
/* XXX: patch interrupt size */
|
||||
|
@ -118,7 +120,7 @@ static const uint8_t qemu_hub_config_descriptor[] = {
|
|||
5: Remote wakeup,
|
||||
4..0: resvd */
|
||||
0x00, /* u8 MaxPower; */
|
||||
|
||||
|
||||
/* USB 1.1:
|
||||
* USB 2.0, single TT organization (mandatory):
|
||||
* one interface, protocol 0
|
||||
|
@ -131,435 +133,475 @@ static const uint8_t qemu_hub_config_descriptor[] = {
|
|||
*/
|
||||
|
||||
/* one interface */
|
||||
0x09, /* u8 if_bLength; */
|
||||
0x04, /* u8 if_bDescriptorType; Interface */
|
||||
0x00, /* u8 if_bInterfaceNumber; */
|
||||
0x00, /* u8 if_bAlternateSetting; */
|
||||
0x01, /* u8 if_bNumEndpoints; */
|
||||
0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
|
||||
0x00, /* u8 if_bInterfaceSubClass; */
|
||||
0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
|
||||
0x00, /* u8 if_iInterface; */
|
||||
|
||||
0x09, /* u8 if_bLength; */
|
||||
0x04, /* u8 if_bDescriptorType; Interface */
|
||||
0x00, /* u8 if_bInterfaceNumber; */
|
||||
0x00, /* u8 if_bAlternateSetting; */
|
||||
0x01, /* u8 if_bNumEndpoints; */
|
||||
0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
|
||||
0x00, /* u8 if_bInterfaceSubClass; */
|
||||
0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
|
||||
0x00, /* u8 if_iInterface; */
|
||||
|
||||
/* one endpoint (status change endpoint) */
|
||||
0x07, /* u8 ep_bLength; */
|
||||
0x05, /* u8 ep_bDescriptorType; Endpoint */
|
||||
0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
|
||||
0x03, /* u8 ep_bmAttributes; Interrupt */
|
||||
0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
|
||||
0x03, /* u8 ep_bmAttributes; Interrupt */
|
||||
0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
|
||||
0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
|
||||
};
|
||||
|
||||
static const uint8_t qemu_hub_hub_descriptor[] =
|
||||
{
|
||||
0x00, /* u8 bLength; patched in later */
|
||||
0x29, /* u8 bDescriptorType; Hub-descriptor */
|
||||
0x00, /* u8 bNbrPorts; (patched later) */
|
||||
0x0a, /* u16 wHubCharacteristics; */
|
||||
0x00, /* (per-port OC, no power switching) */
|
||||
0x01, /* u8 bPwrOn2pwrGood; 2ms */
|
||||
0x00 /* u8 bHubContrCurrent; 0 mA */
|
||||
{
|
||||
0x00, /* u8 bLength; patched in later */
|
||||
0x29, /* u8 bDescriptorType; Hub-descriptor */
|
||||
0x00, /* u8 bNbrPorts; (patched later) */
|
||||
0x0a, /* u16 wHubCharacteristics; */
|
||||
0x00, /* (per-port OC, no power switching) */
|
||||
0x01, /* u8 bPwrOn2pwrGood; 2ms */
|
||||
0x00 /* u8 bHubContrCurrent; 0 mA */
|
||||
|
||||
/* DeviceRemovable and PortPwrCtrlMask patched in later */
|
||||
/* DeviceRemovable and PortPwrCtrlMask patched in later */
|
||||
};
|
||||
|
||||
static void usb_hub_attach(USBPort *port1, USBDevice *dev)
|
||||
static void usb_hub_attach(USBPort* port1, USBDevice* dev)
|
||||
{
|
||||
USBHubState *s =(USBHubState *) port1->opaque;
|
||||
USBHubPort *port = (USBHubPort *)&s->ports[port1->index];
|
||||
|
||||
if (dev) {
|
||||
if (port->port.dev)
|
||||
usb_attach(port1, NULL);
|
||||
|
||||
port->wPortStatus |= PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (dev->speed == USB_SPEED_LOW)
|
||||
port->wPortStatus |= PORT_STAT_LOW_SPEED;
|
||||
else
|
||||
port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
|
||||
port->port.dev = dev;
|
||||
/* send the attach message */
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_ATTACH, 0, 0, NULL, 0);
|
||||
} else {
|
||||
dev = port->port.dev;
|
||||
if (dev) {
|
||||
port->wPortStatus &= ~PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (port->wPortStatus & PORT_STAT_ENABLE) {
|
||||
port->wPortStatus &= ~PORT_STAT_ENABLE;
|
||||
port->wPortChange |= PORT_STAT_C_ENABLE;
|
||||
}
|
||||
/* send the detach message */
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_DETACH, 0, 0, NULL, 0);
|
||||
port->port.dev = NULL;
|
||||
}
|
||||
}
|
||||
USBHubState* s = (USBHubState*)port1->opaque;
|
||||
USBHubPort* port = (USBHubPort*)&s->ports[port1->index];
|
||||
|
||||
if (dev)
|
||||
{
|
||||
if (port->port.dev)
|
||||
usb_attach(port1, NULL);
|
||||
|
||||
port->wPortStatus |= PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (dev->speed == USB_SPEED_LOW)
|
||||
port->wPortStatus |= PORT_STAT_LOW_SPEED;
|
||||
else
|
||||
port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
|
||||
port->port.dev = dev;
|
||||
/* send the attach message */
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_ATTACH, 0, 0, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev = port->port.dev;
|
||||
if (dev)
|
||||
{
|
||||
port->wPortStatus &= ~PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (port->wPortStatus & PORT_STAT_ENABLE)
|
||||
{
|
||||
port->wPortStatus &= ~PORT_STAT_ENABLE;
|
||||
port->wPortChange |= PORT_STAT_C_ENABLE;
|
||||
}
|
||||
/* send the detach message */
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_DETACH, 0, 0, NULL, 0);
|
||||
port->port.dev = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_hub_handle_reset(USBDevice *dev)
|
||||
static void usb_hub_handle_reset(USBDevice* dev)
|
||||
{
|
||||
/* XXX: do it */
|
||||
/* XXX: do it */
|
||||
}
|
||||
|
||||
static int usb_hub_handle_control(USBDevice *dev, int request, int value,
|
||||
int index, int length, uint8_t *data)
|
||||
static int usb_hub_handle_control(USBDevice* dev, int request, int value,
|
||||
int index, int length, uint8_t* data)
|
||||
{
|
||||
USBHubState *s = (USBHubState *)dev;
|
||||
int ret;
|
||||
USBHubState* s = (USBHubState*)dev;
|
||||
int ret;
|
||||
|
||||
switch(request) {
|
||||
case DeviceRequest | USB_REQ_GET_STATUS:
|
||||
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
|
||||
(dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
|
||||
data[1] = 0x00;
|
||||
ret = 2;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
|
||||
if (value == USB_DEVICE_REMOTE_WAKEUP) {
|
||||
dev->remote_wakeup = 0;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
|
||||
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) {
|
||||
dev->remote_wakeup = 1;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
|
||||
dev->addr = value;
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
|
||||
switch(value >> 8) {
|
||||
case USB_DT_DEVICE:
|
||||
memcpy(data, qemu_hub_dev_descriptor,
|
||||
sizeof(qemu_hub_dev_descriptor));
|
||||
ret = sizeof(qemu_hub_dev_descriptor);
|
||||
break;
|
||||
case USB_DT_CONFIG:
|
||||
memcpy(data, qemu_hub_config_descriptor,
|
||||
sizeof(qemu_hub_config_descriptor));
|
||||
switch (request)
|
||||
{
|
||||
case DeviceRequest | USB_REQ_GET_STATUS:
|
||||
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
|
||||
(dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
|
||||
data[1] = 0x00;
|
||||
ret = 2;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
|
||||
if (value == USB_DEVICE_REMOTE_WAKEUP)
|
||||
{
|
||||
dev->remote_wakeup = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
|
||||
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)
|
||||
{
|
||||
dev->remote_wakeup = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
|
||||
dev->addr = value;
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
|
||||
switch (value >> 8)
|
||||
{
|
||||
case USB_DT_DEVICE:
|
||||
memcpy(data, qemu_hub_dev_descriptor,
|
||||
sizeof(qemu_hub_dev_descriptor));
|
||||
ret = sizeof(qemu_hub_dev_descriptor);
|
||||
break;
|
||||
case USB_DT_CONFIG:
|
||||
memcpy(data, qemu_hub_config_descriptor,
|
||||
sizeof(qemu_hub_config_descriptor));
|
||||
|
||||
/* status change endpoint size based on number
|
||||
/* status change endpoint size based on number
|
||||
* of ports */
|
||||
data[22] = (s->nb_ports + 1 + 7) / 8;
|
||||
data[22] = (s->nb_ports + 1 + 7) / 8;
|
||||
|
||||
ret = sizeof(qemu_hub_config_descriptor);
|
||||
break;
|
||||
case USB_DT_STRING:
|
||||
switch(value & 0xff) {
|
||||
case 0:
|
||||
/* language ids */
|
||||
data[0] = 4;
|
||||
data[1] = 3;
|
||||
data[2] = 0x09;
|
||||
data[3] = 0x04;
|
||||
ret = 4;
|
||||
break;
|
||||
case 1:
|
||||
/* serial number */
|
||||
ret = set_usb_string(data, "314159");
|
||||
break;
|
||||
case 2:
|
||||
/* product description */
|
||||
ret = set_usb_string(data, "QEMU USB Hub");
|
||||
break;
|
||||
case 3:
|
||||
/* vendor description */
|
||||
ret = set_usb_string(data, "PCSX2/QEMU");
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
|
||||
data[0] = 1;
|
||||
ret = 1;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_INTERFACE:
|
||||
data[0] = 0;
|
||||
ret = 1;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
|
||||
ret = 0;
|
||||
break;
|
||||
/* usb specific requests */
|
||||
case GetHubStatus:
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
ret = 4;
|
||||
break;
|
||||
case GetPortStatus:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort *port;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
data[0] = port->wPortStatus;
|
||||
data[1] = port->wPortStatus >> 8;
|
||||
data[2] = port->wPortChange;
|
||||
data[3] = port->wPortChange >> 8;
|
||||
ret = 4;
|
||||
}
|
||||
break;
|
||||
case SetHubFeature:
|
||||
case ClearHubFeature:
|
||||
if (value == 0 || value == 1) {
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case SetPortFeature:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort *port;
|
||||
USBDevice *dev;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
dev = port->port.dev;
|
||||
switch(value) {
|
||||
case PORT_SUSPEND:
|
||||
port->wPortStatus |= PORT_STAT_SUSPEND;
|
||||
break;
|
||||
case PORT_RESET:
|
||||
if (dev) {
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_RESET, 0, 0, NULL, 0);
|
||||
port->wPortChange |= PORT_STAT_C_RESET;
|
||||
/* set enable bit */
|
||||
port->wPortStatus |= PORT_STAT_ENABLE;
|
||||
}
|
||||
break;
|
||||
case PORT_POWER:
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case ClearPortFeature:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort *port;
|
||||
USBDevice *dev;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
dev = port->port.dev;
|
||||
switch(value) {
|
||||
case PORT_ENABLE:
|
||||
port->wPortStatus &= ~PORT_STAT_ENABLE;
|
||||
break;
|
||||
case PORT_C_ENABLE:
|
||||
port->wPortChange &= ~PORT_STAT_C_ENABLE;
|
||||
break;
|
||||
case PORT_SUSPEND:
|
||||
port->wPortStatus &= ~PORT_STAT_SUSPEND;
|
||||
break;
|
||||
case PORT_C_SUSPEND:
|
||||
port->wPortChange &= ~PORT_STAT_C_SUSPEND;
|
||||
break;
|
||||
case PORT_C_CONNECTION:
|
||||
port->wPortChange &= ~PORT_STAT_C_CONNECTION;
|
||||
break;
|
||||
case PORT_C_OVERCURRENT:
|
||||
port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
|
||||
break;
|
||||
case PORT_C_RESET:
|
||||
port->wPortChange &= ~PORT_STAT_C_RESET;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case GetHubDescriptor:
|
||||
{
|
||||
unsigned int n, limit, var_hub_size = 0;
|
||||
memcpy(data, qemu_hub_hub_descriptor,
|
||||
sizeof(qemu_hub_hub_descriptor));
|
||||
data[2] = s->nb_ports;
|
||||
ret = sizeof(qemu_hub_config_descriptor);
|
||||
break;
|
||||
case USB_DT_STRING:
|
||||
switch (value & 0xff)
|
||||
{
|
||||
case 0:
|
||||
/* language ids */
|
||||
data[0] = 4;
|
||||
data[1] = 3;
|
||||
data[2] = 0x09;
|
||||
data[3] = 0x04;
|
||||
ret = 4;
|
||||
break;
|
||||
case 1:
|
||||
/* serial number */
|
||||
ret = set_usb_string(data, "314159");
|
||||
break;
|
||||
case 2:
|
||||
/* product description */
|
||||
ret = set_usb_string(data, "QEMU USB Hub");
|
||||
break;
|
||||
case 3:
|
||||
/* vendor description */
|
||||
ret = set_usb_string(data, "PCSX2/QEMU");
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
|
||||
data[0] = 1;
|
||||
ret = 1;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
|
||||
ret = 0;
|
||||
break;
|
||||
case DeviceRequest | USB_REQ_GET_INTERFACE:
|
||||
data[0] = 0;
|
||||
ret = 1;
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
|
||||
ret = 0;
|
||||
break;
|
||||
/* usb specific requests */
|
||||
case GetHubStatus:
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
ret = 4;
|
||||
break;
|
||||
case GetPortStatus:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort* port;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
data[0] = port->wPortStatus;
|
||||
data[1] = port->wPortStatus >> 8;
|
||||
data[2] = port->wPortChange;
|
||||
data[3] = port->wPortChange >> 8;
|
||||
ret = 4;
|
||||
}
|
||||
break;
|
||||
case SetHubFeature:
|
||||
case ClearHubFeature:
|
||||
if (value == 0 || value == 1)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case SetPortFeature:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort* port;
|
||||
USBDevice* dev;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
dev = port->port.dev;
|
||||
switch (value)
|
||||
{
|
||||
case PORT_SUSPEND:
|
||||
port->wPortStatus |= PORT_STAT_SUSPEND;
|
||||
break;
|
||||
case PORT_RESET:
|
||||
if (dev)
|
||||
{
|
||||
dev->handle_packet(dev,
|
||||
USB_MSG_RESET, 0, 0, NULL, 0);
|
||||
port->wPortChange |= PORT_STAT_C_RESET;
|
||||
/* set enable bit */
|
||||
port->wPortStatus |= PORT_STAT_ENABLE;
|
||||
}
|
||||
break;
|
||||
case PORT_POWER:
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case ClearPortFeature:
|
||||
{
|
||||
unsigned int n = index - 1;
|
||||
USBHubPort* port;
|
||||
USBDevice* dev;
|
||||
if (n >= s->nb_ports)
|
||||
goto fail;
|
||||
port = &s->ports[n];
|
||||
dev = port->port.dev;
|
||||
switch (value)
|
||||
{
|
||||
case PORT_ENABLE:
|
||||
port->wPortStatus &= ~PORT_STAT_ENABLE;
|
||||
break;
|
||||
case PORT_C_ENABLE:
|
||||
port->wPortChange &= ~PORT_STAT_C_ENABLE;
|
||||
break;
|
||||
case PORT_SUSPEND:
|
||||
port->wPortStatus &= ~PORT_STAT_SUSPEND;
|
||||
break;
|
||||
case PORT_C_SUSPEND:
|
||||
port->wPortChange &= ~PORT_STAT_C_SUSPEND;
|
||||
break;
|
||||
case PORT_C_CONNECTION:
|
||||
port->wPortChange &= ~PORT_STAT_C_CONNECTION;
|
||||
break;
|
||||
case PORT_C_OVERCURRENT:
|
||||
port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
|
||||
break;
|
||||
case PORT_C_RESET:
|
||||
port->wPortChange &= ~PORT_STAT_C_RESET;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case GetHubDescriptor:
|
||||
{
|
||||
unsigned int n, limit, var_hub_size = 0;
|
||||
memcpy(data, qemu_hub_hub_descriptor,
|
||||
sizeof(qemu_hub_hub_descriptor));
|
||||
data[2] = s->nb_ports;
|
||||
|
||||
/* fill DeviceRemovable bits */
|
||||
limit = ((s->nb_ports + 1 + 7) / 8) + 7;
|
||||
for (n = 7; n < limit; n++) {
|
||||
data[n] = 0x00;
|
||||
var_hub_size++;
|
||||
}
|
||||
/* fill DeviceRemovable bits */
|
||||
limit = ((s->nb_ports + 1 + 7) / 8) + 7;
|
||||
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++) {
|
||||
data[n] = 0xff;
|
||||
var_hub_size++;
|
||||
}
|
||||
/* fill PortPwrCtrlMask bits */
|
||||
limit = limit + ((s->nb_ports + 7) / 8);
|
||||
for (; n < limit; n++)
|
||||
{
|
||||
data[n] = 0xff;
|
||||
var_hub_size++;
|
||||
}
|
||||
|
||||
ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
|
||||
data[0] = ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail:
|
||||
ret = USB_RET_STALL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
|
||||
data[0] = ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail:
|
||||
ret = USB_RET_STALL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usb_hub_handle_data(USBDevice *dev, int pid,
|
||||
uint8_t devep, uint8_t *data, int len)
|
||||
static int usb_hub_handle_data(USBDevice* dev, int pid,
|
||||
uint8_t devep, uint8_t* data, int len)
|
||||
{
|
||||
USBHubState *s = (USBHubState *)dev;
|
||||
int ret;
|
||||
USBHubState* s = (USBHubState*)dev;
|
||||
int ret;
|
||||
|
||||
switch(pid) {
|
||||
case USB_TOKEN_IN:
|
||||
if (devep == 1) {
|
||||
USBHubPort *port;
|
||||
unsigned int status;
|
||||
int i, n;
|
||||
n = (s->nb_ports + 1 + 7) / 8;
|
||||
if (len == 1) { /* FreeBSD workaround */
|
||||
n = 1;
|
||||
} else if (n > len) {
|
||||
return USB_RET_BABBLE;
|
||||
}
|
||||
status = 0;
|
||||
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++) {
|
||||
data[i] = status >> (8 * i);
|
||||
}
|
||||
ret = n;
|
||||
} else {
|
||||
ret = USB_RET_NAK; /* usb11 11.13.1 */
|
||||
}
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case USB_TOKEN_OUT:
|
||||
default:
|
||||
fail:
|
||||
ret = USB_RET_STALL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
switch (pid)
|
||||
{
|
||||
case USB_TOKEN_IN:
|
||||
if (devep == 1)
|
||||
{
|
||||
USBHubPort* port;
|
||||
unsigned int status;
|
||||
int i, n;
|
||||
n = (s->nb_ports + 1 + 7) / 8;
|
||||
if (len == 1)
|
||||
{ /* FreeBSD workaround */
|
||||
n = 1;
|
||||
}
|
||||
else if (n > len)
|
||||
{
|
||||
return USB_RET_BABBLE;
|
||||
}
|
||||
status = 0;
|
||||
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++)
|
||||
{
|
||||
data[i] = status >> (8 * i);
|
||||
}
|
||||
ret = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = USB_RET_NAK; /* usb11 11.13.1 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case USB_TOKEN_OUT:
|
||||
default:
|
||||
fail:
|
||||
ret = USB_RET_STALL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usb_hub_broadcast_packet(USBHubState *s, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t *data, int len)
|
||||
static int usb_hub_broadcast_packet(USBHubState* s, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t* data, int len)
|
||||
{
|
||||
USBHubPort *port;
|
||||
USBDevice *dev;
|
||||
int i, ret;
|
||||
USBHubPort* port;
|
||||
USBDevice* dev;
|
||||
int i, ret;
|
||||
|
||||
for(i = 0; i < s->nb_ports; i++) {
|
||||
port = &s->ports[i];
|
||||
dev = port->port.dev;
|
||||
if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
|
||||
ret = dev->handle_packet(dev, pid,
|
||||
devaddr, devep,
|
||||
data, len);
|
||||
if (ret != USB_RET_NODEV) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return USB_RET_NODEV;
|
||||
for (i = 0; i < s->nb_ports; i++)
|
||||
{
|
||||
port = &s->ports[i];
|
||||
dev = port->port.dev;
|
||||
if (dev && (port->wPortStatus & PORT_STAT_ENABLE))
|
||||
{
|
||||
ret = dev->handle_packet(dev, pid,
|
||||
devaddr, devep,
|
||||
data, len);
|
||||
if (ret != USB_RET_NODEV)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return USB_RET_NODEV;
|
||||
}
|
||||
|
||||
static int usb_hub_handle_packet(USBDevice *dev, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t *data, int len)
|
||||
static int usb_hub_handle_packet(USBDevice* dev, int pid,
|
||||
uint8_t devaddr, uint8_t devep,
|
||||
uint8_t* data, int len)
|
||||
{
|
||||
USBHubState *s = (USBHubState *)dev;
|
||||
USBHubState* s = (USBHubState*)dev;
|
||||
|
||||
#if defined(DEBUG) && 0
|
||||
printf("usb_hub: pid=0x%x\n", pid);
|
||||
printf("usb_hub: pid=0x%x\n", pid);
|
||||
#endif
|
||||
if (dev->state == USB_STATE_DEFAULT &&
|
||||
dev->addr != 0 &&
|
||||
devaddr != dev->addr &&
|
||||
(pid == USB_TOKEN_SETUP ||
|
||||
pid == USB_TOKEN_OUT ||
|
||||
pid == USB_TOKEN_IN)) {
|
||||
/* broadcast the packet to the devices */
|
||||
return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
|
||||
}
|
||||
return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
|
||||
if (dev->state == USB_STATE_DEFAULT &&
|
||||
dev->addr != 0 &&
|
||||
devaddr != dev->addr &&
|
||||
(pid == USB_TOKEN_SETUP ||
|
||||
pid == USB_TOKEN_OUT ||
|
||||
pid == USB_TOKEN_IN))
|
||||
{
|
||||
/* broadcast the packet to the devices */
|
||||
return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
|
||||
}
|
||||
return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
|
||||
}
|
||||
|
||||
static void usb_hub_handle_destroy(USBDevice *dev)
|
||||
static void usb_hub_handle_destroy(USBDevice* dev)
|
||||
{
|
||||
USBHubState *s = (USBHubState *)dev;
|
||||
USBHubState* s = (USBHubState*)dev;
|
||||
|
||||
free(s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
USBDevice *usb_hub_init(int nb_ports)
|
||||
USBDevice* usb_hub_init(int nb_ports)
|
||||
{
|
||||
USBHubState *s;
|
||||
USBHubPort *port;
|
||||
int i;
|
||||
USBHubState* s;
|
||||
USBHubPort* port;
|
||||
int i;
|
||||
|
||||
if (nb_ports > MAX_PORTS)
|
||||
return NULL;
|
||||
s = (USBHubState *)qemu_mallocz(sizeof(USBHubState));
|
||||
if (!s)
|
||||
return NULL;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.handle_packet = usb_hub_handle_packet;
|
||||
if (nb_ports > MAX_PORTS)
|
||||
return NULL;
|
||||
s = (USBHubState*)qemu_mallocz(sizeof(USBHubState));
|
||||
if (!s)
|
||||
return NULL;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.handle_packet = usb_hub_handle_packet;
|
||||
|
||||
/* generic USB device init */
|
||||
s->dev.handle_reset = usb_hub_handle_reset;
|
||||
s->dev.handle_control = usb_hub_handle_control;
|
||||
s->dev.handle_data = usb_hub_handle_data;
|
||||
s->dev.handle_destroy = usb_hub_handle_destroy;
|
||||
/* generic USB device init */
|
||||
s->dev.handle_reset = usb_hub_handle_reset;
|
||||
s->dev.handle_control = usb_hub_handle_control;
|
||||
s->dev.handle_data = usb_hub_handle_data;
|
||||
s->dev.handle_destroy = usb_hub_handle_destroy;
|
||||
|
||||
strncpy(s->dev.devname, "QEMU USB Hub", sizeof(s->dev.devname));
|
||||
strncpy(s->dev.devname, "QEMU USB Hub", sizeof(s->dev.devname));
|
||||
|
||||
s->nb_ports = nb_ports;
|
||||
for(i = 0; i < s->nb_ports; i++) {
|
||||
port = &s->ports[i];
|
||||
s->nb_ports = nb_ports;
|
||||
for (i = 0; i < s->nb_ports; i++)
|
||||
{
|
||||
port = &s->ports[i];
|
||||
port->port.opaque = s;
|
||||
port->port.index = i;
|
||||
port->port.attach = usb_hub_attach;
|
||||
port->wPortStatus = PORT_STAT_POWER;
|
||||
port->wPortChange = 0;
|
||||
}
|
||||
return (USBDevice *)s;
|
||||
port->wPortStatus = PORT_STAT_POWER;
|
||||
port->wPortChange = 0;
|
||||
}
|
||||
return (USBDevice*)s;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,23 +18,25 @@
|
|||
/* compute with 96 bit intermediate result: (a*b)/c */
|
||||
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
|
||||
{
|
||||
union {
|
||||
uint64_t ll;
|
||||
struct {
|
||||
union
|
||||
{
|
||||
uint64_t ll;
|
||||
struct
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
uint32_t high, low;
|
||||
uint32_t high, low;
|
||||
#else
|
||||
uint32_t low, high;
|
||||
#endif
|
||||
} l;
|
||||
} u, res;
|
||||
uint64_t rl, rh;
|
||||
uint32_t low, high;
|
||||
#endif
|
||||
} l;
|
||||
} u, res;
|
||||
uint64_t rl, rh;
|
||||
|
||||
u.ll = a;
|
||||
rl = (uint64_t)u.l.low * (uint64_t)b;
|
||||
rh = (uint64_t)u.l.high * (uint64_t)b;
|
||||
rh += (rl >> 32);
|
||||
res.l.high = rh / c;
|
||||
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
|
||||
return res.ll;
|
||||
u.ll = a;
|
||||
rl = (uint64_t)u.l.low * (uint64_t)b;
|
||||
rh = (uint64_t)u.l.high * (uint64_t)b;
|
||||
rh += (rl >> 32);
|
||||
res.l.high = rh / c;
|
||||
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
|
||||
return res.ll;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
#include "qusb.h"
|
||||
|
||||
#ifndef glue
|
||||
#define xglue(x, y) x ## y
|
||||
#define xglue(x, y) x##y
|
||||
#define glue(x, y) xglue(x, y)
|
||||
#define stringify(s) tostring(s)
|
||||
#define tostring(s) #s
|
||||
#define stringify(s) tostring(s)
|
||||
#define tostring(s) #s
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
|
@ -68,19 +68,19 @@
|
|||
|
||||
/* vl.c */
|
||||
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
|
||||
int cpu_physical_memory_rw(uint32_t addr, uint8_t *buf,
|
||||
size_t len, int is_write);
|
||||
int cpu_physical_memory_rw(uint32_t addr, uint8_t* buf,
|
||||
size_t len, int is_write);
|
||||
|
||||
inline int cpu_physical_memory_read(uint32_t addr,
|
||||
uint8_t *buf, size_t len)
|
||||
uint8_t* buf, size_t len)
|
||||
{
|
||||
return cpu_physical_memory_rw(addr, buf, len, 0);
|
||||
}
|
||||
|
||||
inline int cpu_physical_memory_write(uint32_t addr,
|
||||
const uint8_t *buf, size_t len)
|
||||
const uint8_t* buf, size_t len)
|
||||
{
|
||||
return cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
|
||||
return cpu_physical_memory_rw(addr, (uint8_t*)buf, len, 1);
|
||||
}
|
||||
|
||||
#endif /* VL_H */
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#if defined(AE_VCPP) || defined(AE_ICC)
|
||||
#define AE_FORCEINLINE __forceinline
|
||||
#elif defined(AE_GCC)
|
||||
//#define AE_FORCEINLINE __attribute__((always_inline))
|
||||
//#define AE_FORCEINLINE __attribute__((always_inline))
|
||||
#define AE_FORCEINLINE inline
|
||||
#else
|
||||
#define AE_FORCEINLINE inline
|
||||
|
@ -67,21 +67,23 @@
|
|||
|
||||
// Portable atomic fences implemented below:
|
||||
|
||||
namespace moodycamel {
|
||||
namespace moodycamel
|
||||
{
|
||||
|
||||
enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
enum memory_order
|
||||
{
|
||||
memory_order_relaxed,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
|
||||
// memory_order_sync: Forces a full sync:
|
||||
// #LoadLoad, #LoadStore, #StoreStore, and most significantly, #StoreLoad
|
||||
memory_order_sync = memory_order_seq_cst
|
||||
};
|
||||
// memory_order_sync: Forces a full sync:
|
||||
// #LoadLoad, #LoadStore, #StoreStore, and most significantly, #StoreLoad
|
||||
memory_order_sync = memory_order_seq_cst
|
||||
};
|
||||
|
||||
} // end namespace moodycamel
|
||||
} // end namespace moodycamel
|
||||
|
||||
#if (defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli))) || (defined(AE_ICC) && __INTEL_COMPILER < 1600)
|
||||
// VS2010 and ICC13 don't support std::atomic_*_fence, implement our own fences
|
||||
|
@ -103,108 +105,154 @@ enum memory_order {
|
|||
|
||||
#ifdef AE_VCPP
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4365) // Disable erroneous 'conversion from long to unsigned int, signed/unsigned mismatch' error when using `assert`
|
||||
#pragma warning(disable : 4365) // Disable erroneous 'conversion from long to unsigned int, signed/unsigned mismatch' error when using `assert`
|
||||
#ifdef __cplusplus_cli
|
||||
#pragma managed(push, off)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace moodycamel {
|
||||
|
||||
AE_FORCEINLINE void compiler_fence(memory_order order)
|
||||
namespace moodycamel
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// x86/x64 have a strong memory model -- all loads and stores have
|
||||
// acquire and release semantics automatically (so only need compiler
|
||||
// barriers for those).
|
||||
#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;
|
||||
case memory_order_seq_cst:
|
||||
_ReadWriteBarrier();
|
||||
AeFullSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
default: assert(false);
|
||||
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;
|
||||
case memory_order_seq_cst:
|
||||
_ReadWriteBarrier();
|
||||
AeFullSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
AE_FORCEINLINE void fence(memory_order order)
|
||||
{
|
||||
// Non-specialized arch, use heavier memory barriers everywhere just in case :-(
|
||||
switch (order) {
|
||||
case memory_order_relaxed:
|
||||
break;
|
||||
case memory_order_acquire:
|
||||
_ReadBarrier();
|
||||
AeLiteSync();
|
||||
_ReadBarrier();
|
||||
break;
|
||||
case memory_order_release:
|
||||
_WriteBarrier();
|
||||
AeLiteSync();
|
||||
_WriteBarrier();
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
_ReadWriteBarrier();
|
||||
AeLiteSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
case memory_order_seq_cst:
|
||||
_ReadWriteBarrier();
|
||||
AeFullSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
default: assert(false);
|
||||
AE_FORCEINLINE void fence(memory_order order)
|
||||
{
|
||||
// Non-specialized arch, use heavier memory barriers everywhere just in case :-(
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
break;
|
||||
case memory_order_acquire:
|
||||
_ReadBarrier();
|
||||
AeLiteSync();
|
||||
_ReadBarrier();
|
||||
break;
|
||||
case memory_order_release:
|
||||
_WriteBarrier();
|
||||
AeLiteSync();
|
||||
_WriteBarrier();
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
_ReadWriteBarrier();
|
||||
AeLiteSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
case memory_order_seq_cst:
|
||||
_ReadWriteBarrier();
|
||||
AeFullSync();
|
||||
_ReadWriteBarrier();
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // end namespace moodycamel
|
||||
} // end namespace moodycamel
|
||||
#else
|
||||
// Use standard library of atomics
|
||||
#include <atomic>
|
||||
|
||||
namespace moodycamel {
|
||||
|
||||
AE_FORCEINLINE void compiler_fence(memory_order order)
|
||||
namespace moodycamel
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace moodycamel
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace moodycamel
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -222,102 +270,132 @@ 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 {
|
||||
template<typename T>
|
||||
class weak_atomic
|
||||
namespace moodycamel
|
||||
{
|
||||
public:
|
||||
weak_atomic() { }
|
||||
template <typename T>
|
||||
class weak_atomic
|
||||
{
|
||||
public:
|
||||
weak_atomic() {}
|
||||
#ifdef AE_VCPP
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4100) // Get rid of (erroneous) 'unreferenced formal parameter' warning
|
||||
#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) { }
|
||||
// Work around bug with universal reference/nullptr combination that only appears when /clr is on
|
||||
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; }
|
||||
|
||||
AE_FORCEINLINE T load() const { return value; }
|
||||
|
||||
AE_FORCEINLINE T fetch_add_acquire(T increment)
|
||||
{
|
||||
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
|
||||
#endif
|
||||
assert(false && "T must be either a 32 or 64 bit type");
|
||||
return value;
|
||||
}
|
||||
|
||||
AE_FORCEINLINE T fetch_add_release(T increment)
|
||||
{
|
||||
assert(false && "T must be either a 32 or 64 bit type");
|
||||
return value;
|
||||
}
|
||||
|
||||
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
|
||||
#endif
|
||||
assert(false && "T must be either a 32 or 64 bit type");
|
||||
return value;
|
||||
}
|
||||
assert(false && "T must be either a 32 or 64 bit type");
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
template<typename U>
|
||||
AE_FORCEINLINE weak_atomic const& operator=(U&& x)
|
||||
{
|
||||
value.store(std::forward<U>(x), std::memory_order_relaxed);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AE_FORCEINLINE weak_atomic const& operator=(weak_atomic const& other)
|
||||
{
|
||||
value.store(other.value.load(std::memory_order_relaxed), std::memory_order_relaxed);
|
||||
return *this;
|
||||
}
|
||||
template <typename U>
|
||||
AE_FORCEINLINE weak_atomic const& operator=(U&& x)
|
||||
{
|
||||
value.store(std::forward<U>(x), std::memory_order_relaxed);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AE_FORCEINLINE T load() const { return value.load(std::memory_order_relaxed); }
|
||||
|
||||
AE_FORCEINLINE T fetch_add_acquire(T increment)
|
||||
{
|
||||
return value.fetch_add(increment, std::memory_order_acquire);
|
||||
}
|
||||
|
||||
AE_FORCEINLINE T fetch_add_release(T increment)
|
||||
{
|
||||
return value.fetch_add(increment, std::memory_order_release);
|
||||
}
|
||||
AE_FORCEINLINE weak_atomic const& operator=(weak_atomic const& other)
|
||||
{
|
||||
value.store(other.value.load(std::memory_order_relaxed), std::memory_order_relaxed);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AE_FORCEINLINE T load() const { return value.load(std::memory_order_relaxed); }
|
||||
|
||||
AE_FORCEINLINE T fetch_add_acquire(T increment)
|
||||
{
|
||||
return value.fetch_add(increment, std::memory_order_acquire);
|
||||
}
|
||||
|
||||
AE_FORCEINLINE T fetch_add_release(T increment)
|
||||
{
|
||||
return value.fetch_add(increment, std::memory_order_release);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
#ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
|
||||
// No std::atomic support, but still need to circumvent compiler optimizations.
|
||||
// `volatile` will make memory access slow, but is guaranteed to be reliable.
|
||||
volatile T value;
|
||||
// No std::atomic support, but still need to circumvent compiler optimizations.
|
||||
// `volatile` will make memory access slow, but is guaranteed to be reliable.
|
||||
volatile T value;
|
||||
#else
|
||||
std::atomic<T> value;
|
||||
std::atomic<T> value;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace moodycamel
|
||||
} // end namespace moodycamel
|
||||
|
||||
|
||||
|
||||
|
@ -330,11 +408,11 @@ private:
|
|||
// I know this is an ugly hack but it still beats polluting the global
|
||||
// namespace with thousands of generic names or adding a .cpp for nothing.
|
||||
extern "C" {
|
||||
struct _SECURITY_ATTRIBUTES;
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName);
|
||||
__declspec(dllimport) int __stdcall CloseHandle(void* hObject);
|
||||
__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds);
|
||||
__declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount);
|
||||
struct _SECURITY_ATTRIBUTES;
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName);
|
||||
__declspec(dllimport) int __stdcall CloseHandle(void* hObject);
|
||||
__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds);
|
||||
__declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount);
|
||||
}
|
||||
#elif defined(__MACH__)
|
||||
#include <mach/mach.h>
|
||||
|
@ -371,29 +449,29 @@ namespace moodycamel
|
|||
class Semaphore
|
||||
{
|
||||
private:
|
||||
void* m_hSema;
|
||||
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
void* m_hSema;
|
||||
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
const long maxLong = 0x7fffffff;
|
||||
m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
|
||||
}
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
const long maxLong = 0x7fffffff;
|
||||
m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
CloseHandle(m_hSema);
|
||||
}
|
||||
~Semaphore()
|
||||
{
|
||||
CloseHandle(m_hSema);
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
const unsigned long infinite = 0xffffffff;
|
||||
WaitForSingleObject(m_hSema, infinite);
|
||||
}
|
||||
void wait()
|
||||
{
|
||||
const unsigned long infinite = 0xffffffff;
|
||||
WaitForSingleObject(m_hSema, infinite);
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
{
|
||||
|
@ -407,10 +485,10 @@ namespace moodycamel
|
|||
return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) != RC_WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void signal(int count = 1)
|
||||
{
|
||||
ReleaseSemaphore(m_hSema, count, nullptr);
|
||||
}
|
||||
void signal(int count = 1)
|
||||
{
|
||||
ReleaseSemaphore(m_hSema, count, nullptr);
|
||||
}
|
||||
};
|
||||
#elif defined(__MACH__)
|
||||
//---------------------------------------------------------
|
||||
|
@ -420,27 +498,27 @@ namespace moodycamel
|
|||
class Semaphore
|
||||
{
|
||||
private:
|
||||
semaphore_t m_sema;
|
||||
semaphore_t m_sema;
|
||||
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
|
||||
}
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
semaphore_destroy(mach_task_self(), m_sema);
|
||||
}
|
||||
~Semaphore()
|
||||
{
|
||||
semaphore_destroy(mach_task_self(), m_sema);
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
semaphore_wait(m_sema);
|
||||
}
|
||||
void wait()
|
||||
{
|
||||
semaphore_wait(m_sema);
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
{
|
||||
|
@ -459,18 +537,18 @@ namespace moodycamel
|
|||
return rc != KERN_OPERATION_TIMED_OUT && rc != KERN_ABORTED;
|
||||
}
|
||||
|
||||
void signal()
|
||||
{
|
||||
semaphore_signal(m_sema);
|
||||
}
|
||||
void signal()
|
||||
{
|
||||
semaphore_signal(m_sema);
|
||||
}
|
||||
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
semaphore_signal(m_sema);
|
||||
}
|
||||
}
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
semaphore_signal(m_sema);
|
||||
}
|
||||
}
|
||||
};
|
||||
#elif defined(__unix__)
|
||||
//---------------------------------------------------------
|
||||
|
@ -479,38 +557,38 @@ namespace moodycamel
|
|||
class Semaphore
|
||||
{
|
||||
private:
|
||||
sem_t m_sema;
|
||||
sem_t m_sema;
|
||||
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
Semaphore(const Semaphore& other);
|
||||
Semaphore& operator=(const Semaphore& other);
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
sem_init(&m_sema, 0, initialCount);
|
||||
}
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
sem_init(&m_sema, 0, initialCount);
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
sem_destroy(&m_sema);
|
||||
}
|
||||
~Semaphore()
|
||||
{
|
||||
sem_destroy(&m_sema);
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
// http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = sem_wait(&m_sema);
|
||||
}
|
||||
while (rc == -1 && errno == EINTR);
|
||||
}
|
||||
void wait()
|
||||
{
|
||||
// http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = sem_wait(&m_sema);
|
||||
} 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,30 +604,32 @@ 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);
|
||||
}
|
||||
|
||||
void signal()
|
||||
{
|
||||
sem_post(&m_sema);
|
||||
}
|
||||
void signal()
|
||||
{
|
||||
sem_post(&m_sema);
|
||||
}
|
||||
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
sem_post(&m_sema);
|
||||
}
|
||||
}
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
sem_post(&m_sema);
|
||||
}
|
||||
}
|
||||
};
|
||||
#else
|
||||
#error Unsupported platform! (No semaphore wrapper available)
|
||||
|
@ -562,31 +642,31 @@ namespace moodycamel
|
|||
{
|
||||
public:
|
||||
typedef std::make_signed<std::size_t>::type ssize_t;
|
||||
|
||||
private:
|
||||
weak_atomic<ssize_t> m_count;
|
||||
Semaphore m_sema;
|
||||
|
||||
bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
|
||||
{
|
||||
ssize_t oldCount;
|
||||
// Is there a better way to set the initial spin count?
|
||||
// If we lower it to 1000, testBenaphore becomes 15x slower on my Core i7-5930K Windows PC,
|
||||
// as threads start hitting the kernel semaphore.
|
||||
int spin = 10000;
|
||||
while (--spin >= 0)
|
||||
{
|
||||
if (m_count.load() > 0)
|
||||
{
|
||||
m_count.fetch_add_acquire(-1);
|
||||
return true;
|
||||
}
|
||||
compiler_fence(memory_order_acquire); // Prevent the compiler from collapsing the loop.
|
||||
}
|
||||
oldCount = m_count.fetch_add_acquire(-1);
|
||||
private:
|
||||
weak_atomic<ssize_t> m_count;
|
||||
Semaphore m_sema;
|
||||
|
||||
bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
|
||||
{
|
||||
ssize_t oldCount;
|
||||
// Is there a better way to set the initial spin count?
|
||||
// If we lower it to 1000, testBenaphore becomes 15x slower on my Core i7-5930K Windows PC,
|
||||
// as threads start hitting the kernel semaphore.
|
||||
int spin = 10000;
|
||||
while (--spin >= 0)
|
||||
{
|
||||
if (m_count.load() > 0)
|
||||
{
|
||||
m_count.fetch_add_acquire(-1);
|
||||
return true;
|
||||
}
|
||||
compiler_fence(memory_order_acquire); // Prevent the compiler from collapsing the loop.
|
||||
}
|
||||
oldCount = m_count.fetch_add_acquire(-1);
|
||||
if (oldCount > 0)
|
||||
return true;
|
||||
if (timeout_usecs < 0)
|
||||
if (timeout_usecs < 0)
|
||||
{
|
||||
m_sema.wait();
|
||||
return true;
|
||||
|
@ -602,60 +682,61 @@ namespace moodycamel
|
|||
{
|
||||
oldCount = m_count.fetch_add_release(1);
|
||||
if (oldCount < 0)
|
||||
return false; // successfully restored things to the way they were
|
||||
return false; // successfully restored things to the way they were
|
||||
// Oh, the producer thread just signaled the semaphore after all. Try again:
|
||||
oldCount = m_count.fetch_add_acquire(-1);
|
||||
if (oldCount > 0 && m_sema.try_wait())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
LightweightSemaphore(ssize_t initialCount = 0) : m_count(initialCount)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
}
|
||||
LightweightSemaphore(ssize_t initialCount = 0)
|
||||
: m_count(initialCount)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
}
|
||||
|
||||
bool tryWait()
|
||||
{
|
||||
if (m_count.load() > 0)
|
||||
{
|
||||
m_count.fetch_add_acquire(-1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool tryWait()
|
||||
{
|
||||
if (m_count.load() > 0)
|
||||
{
|
||||
m_count.fetch_add_acquire(-1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
if (!tryWait())
|
||||
waitWithPartialSpinning();
|
||||
}
|
||||
void wait()
|
||||
{
|
||||
if (!tryWait())
|
||||
waitWithPartialSpinning();
|
||||
}
|
||||
|
||||
bool wait(std::int64_t timeout_usecs)
|
||||
{
|
||||
return tryWait() || waitWithPartialSpinning(timeout_usecs);
|
||||
}
|
||||
|
||||
void signal(ssize_t count = 1)
|
||||
{
|
||||
assert(count >= 0);
|
||||
ssize_t oldCount = m_count.fetch_add_release(count);
|
||||
assert(oldCount >= -1);
|
||||
if (oldCount < 0)
|
||||
{
|
||||
m_sema.signal(1);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t availableApprox() const
|
||||
{
|
||||
ssize_t count = m_count.load();
|
||||
return count > 0 ? count : 0;
|
||||
}
|
||||
void signal(ssize_t count = 1)
|
||||
{
|
||||
assert(count >= 0);
|
||||
ssize_t oldCount = m_count.fetch_add_release(count);
|
||||
assert(oldCount >= -1);
|
||||
if (oldCount < 0)
|
||||
{
|
||||
m_sema.signal(1);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t availableApprox() const
|
||||
{
|
||||
ssize_t count = m_count.load();
|
||||
return count > 0 ? count : 0;
|
||||
}
|
||||
};
|
||||
} // end namespace spsc_sema
|
||||
} // end namespace moodycamel
|
||||
} // end namespace spsc_sema
|
||||
} // end namespace moodycamel
|
||||
|
||||
#if defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli))
|
||||
#pragma warning(pop)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,36 +33,42 @@ _HidD_GetProductString HidD_GetProductString = NULL;
|
|||
|
||||
static HMODULE hModHid = 0;
|
||||
|
||||
int InitHid() {
|
||||
if (hModHid) {
|
||||
return 1;
|
||||
}
|
||||
hModHid = LoadLibraryA("hid.dll");
|
||||
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")) &&
|
||||
(HidP_GetCaps = (_HidP_GetCaps)GetProcAddress(hModHid, "HidP_GetCaps")) &&
|
||||
(HidD_FreePreparsedData = (_HidD_FreePreparsedData)GetProcAddress(hModHid, "HidD_FreePreparsedData")) &&
|
||||
(HidP_GetSpecificButtonCaps = (_HidP_GetSpecificButtonCaps)GetProcAddress(hModHid, "HidP_GetSpecificButtonCaps")) &&
|
||||
(HidP_GetButtonCaps = (_HidP_GetButtonCaps)GetProcAddress(hModHid, "HidP_GetButtonCaps")) &&
|
||||
(HidP_GetUsages = (_HidP_GetUsages)GetProcAddress(hModHid, "HidP_GetUsages")) &&
|
||||
(HidP_GetValueCaps = (_HidP_GetValueCaps)GetProcAddress(hModHid, "HidP_GetValueCaps")) &&
|
||||
(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"))) {
|
||||
//pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
|
||||
return 1;
|
||||
}
|
||||
UninitHid();
|
||||
}
|
||||
return 0;
|
||||
int InitHid()
|
||||
{
|
||||
if (hModHid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
hModHid = LoadLibraryA("hid.dll");
|
||||
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")) &&
|
||||
(HidP_GetCaps = (_HidP_GetCaps)GetProcAddress(hModHid, "HidP_GetCaps")) &&
|
||||
(HidD_FreePreparsedData = (_HidD_FreePreparsedData)GetProcAddress(hModHid, "HidD_FreePreparsedData")) &&
|
||||
(HidP_GetSpecificButtonCaps = (_HidP_GetSpecificButtonCaps)GetProcAddress(hModHid, "HidP_GetSpecificButtonCaps")) &&
|
||||
(HidP_GetButtonCaps = (_HidP_GetButtonCaps)GetProcAddress(hModHid, "HidP_GetButtonCaps")) &&
|
||||
(HidP_GetUsages = (_HidP_GetUsages)GetProcAddress(hModHid, "HidP_GetUsages")) &&
|
||||
(HidP_GetValueCaps = (_HidP_GetValueCaps)GetProcAddress(hModHid, "HidP_GetValueCaps")) &&
|
||||
(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")))
|
||||
{
|
||||
//pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
|
||||
return 1;
|
||||
}
|
||||
UninitHid();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UninitHid() {
|
||||
if (hModHid) {
|
||||
FreeLibrary(hModHid);
|
||||
hModHid = 0;
|
||||
}
|
||||
void UninitHid()
|
||||
{
|
||||
if (hModHid)
|
||||
{
|
||||
FreeLibrary(hModHid);
|
||||
hModHid = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,74 +20,74 @@
|
|||
|
||||
typedef USHORT USAGE, *PUSAGE;
|
||||
|
||||
#define HID_USAGE_PAGE_GENERIC ((USAGE) 0x01)
|
||||
#define HID_USAGE_PAGE_SIMULATION ((USAGE) 0x02)
|
||||
#define HID_USAGE_PAGE_VR ((USAGE) 0x03)
|
||||
#define HID_USAGE_PAGE_SPORT ((USAGE) 0x04)
|
||||
#define HID_USAGE_PAGE_GAME ((USAGE) 0x05)
|
||||
#define HID_USAGE_PAGE_KEYBOARD ((USAGE) 0x07)
|
||||
#define HID_USAGE_PAGE_LED ((USAGE) 0x08)
|
||||
#define HID_USAGE_PAGE_BUTTON ((USAGE) 0x09)
|
||||
#define HID_USAGE_PAGE_ORDINAL ((USAGE) 0x0A)
|
||||
#define HID_USAGE_PAGE_TELEPHONY ((USAGE) 0x0B)
|
||||
#define HID_USAGE_PAGE_CONSUMER ((USAGE) 0x0C)
|
||||
#define HID_USAGE_PAGE_DIGITIZER ((USAGE) 0x0D)
|
||||
#define HID_USAGE_PAGE_UNICODE ((USAGE) 0x10)
|
||||
#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE) 0x14)
|
||||
#define HID_USAGE_PAGE_GENERIC ((USAGE)0x01)
|
||||
#define HID_USAGE_PAGE_SIMULATION ((USAGE)0x02)
|
||||
#define HID_USAGE_PAGE_VR ((USAGE)0x03)
|
||||
#define HID_USAGE_PAGE_SPORT ((USAGE)0x04)
|
||||
#define HID_USAGE_PAGE_GAME ((USAGE)0x05)
|
||||
#define HID_USAGE_PAGE_KEYBOARD ((USAGE)0x07)
|
||||
#define HID_USAGE_PAGE_LED ((USAGE)0x08)
|
||||
#define HID_USAGE_PAGE_BUTTON ((USAGE)0x09)
|
||||
#define HID_USAGE_PAGE_ORDINAL ((USAGE)0x0A)
|
||||
#define HID_USAGE_PAGE_TELEPHONY ((USAGE)0x0B)
|
||||
#define HID_USAGE_PAGE_CONSUMER ((USAGE)0x0C)
|
||||
#define HID_USAGE_PAGE_DIGITIZER ((USAGE)0x0D)
|
||||
#define HID_USAGE_PAGE_UNICODE ((USAGE)0x10)
|
||||
#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE)0x14)
|
||||
|
||||
|
||||
//
|
||||
// Usages from Generic Desktop Page (0x01)
|
||||
//
|
||||
|
||||
#define HID_USAGE_GENERIC_POINTER ((USAGE) 0x01)
|
||||
#define HID_USAGE_GENERIC_MOUSE ((USAGE) 0x02)
|
||||
#define HID_USAGE_GENERIC_JOYSTICK ((USAGE) 0x04)
|
||||
#define HID_USAGE_GENERIC_GAMEPAD ((USAGE) 0x05)
|
||||
#define HID_USAGE_GENERIC_KEYBOARD ((USAGE) 0x06)
|
||||
#define HID_USAGE_GENERIC_KEYPAD ((USAGE) 0x07)
|
||||
#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE) 0x80)
|
||||
#define HID_USAGE_GENERIC_POINTER ((USAGE)0x01)
|
||||
#define HID_USAGE_GENERIC_MOUSE ((USAGE)0x02)
|
||||
#define HID_USAGE_GENERIC_JOYSTICK ((USAGE)0x04)
|
||||
#define HID_USAGE_GENERIC_GAMEPAD ((USAGE)0x05)
|
||||
#define HID_USAGE_GENERIC_KEYBOARD ((USAGE)0x06)
|
||||
#define HID_USAGE_GENERIC_KEYPAD ((USAGE)0x07)
|
||||
#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE)0x80)
|
||||
|
||||
#define HID_USAGE_GENERIC_X ((USAGE) 0x30)
|
||||
#define HID_USAGE_GENERIC_Y ((USAGE) 0x31)
|
||||
#define HID_USAGE_GENERIC_Z ((USAGE) 0x32)
|
||||
#define HID_USAGE_GENERIC_RX ((USAGE) 0x33)
|
||||
#define HID_USAGE_GENERIC_RY ((USAGE) 0x34)
|
||||
#define HID_USAGE_GENERIC_RZ ((USAGE) 0x35)
|
||||
#define HID_USAGE_GENERIC_SLIDER ((USAGE) 0x36)
|
||||
#define HID_USAGE_GENERIC_DIAL ((USAGE) 0x37)
|
||||
#define HID_USAGE_GENERIC_WHEEL ((USAGE) 0x38)
|
||||
#define HID_USAGE_GENERIC_HATSWITCH ((USAGE) 0x39)
|
||||
#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE) 0x3A)
|
||||
#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE) 0x3B)
|
||||
#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE) 0x3C)
|
||||
#define HID_USAGE_GENERIC_VX ((USAGE) 0x40)
|
||||
#define HID_USAGE_GENERIC_VY ((USAGE) 0x41)
|
||||
#define HID_USAGE_GENERIC_VZ ((USAGE) 0x42)
|
||||
#define HID_USAGE_GENERIC_VBRX ((USAGE) 0x43)
|
||||
#define HID_USAGE_GENERIC_VBRY ((USAGE) 0x44)
|
||||
#define HID_USAGE_GENERIC_VBRZ ((USAGE) 0x45)
|
||||
#define HID_USAGE_GENERIC_VNO ((USAGE) 0x46)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE) 0x81)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE) 0x82)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE) 0x83)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE) 0x84)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE) 0x85)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE) 0x86)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE) 0x87)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE) 0x88)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE) 0x89)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE) 0x8A)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE) 0x8B)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE) 0x8C)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE) 0x8D)
|
||||
#define HID_USAGE_GENERIC_X ((USAGE)0x30)
|
||||
#define HID_USAGE_GENERIC_Y ((USAGE)0x31)
|
||||
#define HID_USAGE_GENERIC_Z ((USAGE)0x32)
|
||||
#define HID_USAGE_GENERIC_RX ((USAGE)0x33)
|
||||
#define HID_USAGE_GENERIC_RY ((USAGE)0x34)
|
||||
#define HID_USAGE_GENERIC_RZ ((USAGE)0x35)
|
||||
#define HID_USAGE_GENERIC_SLIDER ((USAGE)0x36)
|
||||
#define HID_USAGE_GENERIC_DIAL ((USAGE)0x37)
|
||||
#define HID_USAGE_GENERIC_WHEEL ((USAGE)0x38)
|
||||
#define HID_USAGE_GENERIC_HATSWITCH ((USAGE)0x39)
|
||||
#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE)0x3A)
|
||||
#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE)0x3B)
|
||||
#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE)0x3C)
|
||||
#define HID_USAGE_GENERIC_VX ((USAGE)0x40)
|
||||
#define HID_USAGE_GENERIC_VY ((USAGE)0x41)
|
||||
#define HID_USAGE_GENERIC_VZ ((USAGE)0x42)
|
||||
#define HID_USAGE_GENERIC_VBRX ((USAGE)0x43)
|
||||
#define HID_USAGE_GENERIC_VBRY ((USAGE)0x44)
|
||||
#define HID_USAGE_GENERIC_VBRZ ((USAGE)0x45)
|
||||
#define HID_USAGE_GENERIC_VNO ((USAGE)0x46)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE)0x81)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE)0x82)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE)0x83)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE)0x84)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE)0x85)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE)0x86)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE)0x87)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE)0x88)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE)0x89)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE)0x8A)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE)0x8B)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE)0x8C)
|
||||
#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE)0x8D)
|
||||
|
||||
//
|
||||
// Usages from Simulation Controls Page (0x02)
|
||||
//
|
||||
|
||||
#define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA)
|
||||
#define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB)
|
||||
#define HID_USAGE_SIMULATION_RUDDER ((USAGE)0xBA)
|
||||
#define HID_USAGE_SIMULATION_THROTTLE ((USAGE)0xBB)
|
||||
|
||||
//
|
||||
// Virtual Reality Controls Page (0x03)
|
||||
|
@ -109,38 +109,38 @@ typedef USHORT USAGE, *PUSAGE;
|
|||
//
|
||||
|
||||
// Error "keys"
|
||||
#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE) 0x00)
|
||||
#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE) 0x01)
|
||||
#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE) 0x02)
|
||||
#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE) 0x03)
|
||||
#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE)0x00)
|
||||
#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE)0x01)
|
||||
#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE)0x02)
|
||||
#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE)0x03)
|
||||
|
||||
// Letters
|
||||
#define HID_USAGE_KEYBOARD_aA ((USAGE) 0x04)
|
||||
#define HID_USAGE_KEYBOARD_zZ ((USAGE) 0x1D)
|
||||
#define HID_USAGE_KEYBOARD_aA ((USAGE)0x04)
|
||||
#define HID_USAGE_KEYBOARD_zZ ((USAGE)0x1D)
|
||||
// Numbers
|
||||
#define HID_USAGE_KEYBOARD_ONE ((USAGE) 0x1E)
|
||||
#define HID_USAGE_KEYBOARD_ZERO ((USAGE) 0x27)
|
||||
#define HID_USAGE_KEYBOARD_ONE ((USAGE)0x1E)
|
||||
#define HID_USAGE_KEYBOARD_ZERO ((USAGE)0x27)
|
||||
// Modifier Keys
|
||||
#define HID_USAGE_KEYBOARD_LCTRL ((USAGE) 0xE0)
|
||||
#define HID_USAGE_KEYBOARD_LSHFT ((USAGE) 0xE1)
|
||||
#define HID_USAGE_KEYBOARD_LALT ((USAGE) 0xE2)
|
||||
#define HID_USAGE_KEYBOARD_LGUI ((USAGE) 0xE3)
|
||||
#define HID_USAGE_KEYBOARD_RCTRL ((USAGE) 0xE4)
|
||||
#define HID_USAGE_KEYBOARD_RSHFT ((USAGE) 0xE5)
|
||||
#define HID_USAGE_KEYBOARD_RALT ((USAGE) 0xE6)
|
||||
#define HID_USAGE_KEYBOARD_RGUI ((USAGE) 0xE7)
|
||||
#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE) 0x47)
|
||||
#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE) 0x53)
|
||||
#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE) 0x39)
|
||||
#define HID_USAGE_KEYBOARD_LCTRL ((USAGE)0xE0)
|
||||
#define HID_USAGE_KEYBOARD_LSHFT ((USAGE)0xE1)
|
||||
#define HID_USAGE_KEYBOARD_LALT ((USAGE)0xE2)
|
||||
#define HID_USAGE_KEYBOARD_LGUI ((USAGE)0xE3)
|
||||
#define HID_USAGE_KEYBOARD_RCTRL ((USAGE)0xE4)
|
||||
#define HID_USAGE_KEYBOARD_RSHFT ((USAGE)0xE5)
|
||||
#define HID_USAGE_KEYBOARD_RALT ((USAGE)0xE6)
|
||||
#define HID_USAGE_KEYBOARD_RGUI ((USAGE)0xE7)
|
||||
#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE)0x47)
|
||||
#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE)0x53)
|
||||
#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE)0x39)
|
||||
// Funtion keys
|
||||
#define HID_USAGE_KEYBOARD_F1 ((USAGE) 0x3A)
|
||||
#define HID_USAGE_KEYBOARD_F12 ((USAGE) 0x45)
|
||||
#define HID_USAGE_KEYBOARD_F1 ((USAGE)0x3A)
|
||||
#define HID_USAGE_KEYBOARD_F12 ((USAGE)0x45)
|
||||
|
||||
#define HID_USAGE_KEYBOARD_RETURN ((USAGE) 0x28)
|
||||
#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE) 0x29)
|
||||
#define HID_USAGE_KEYBOARD_DELETE ((USAGE) 0x2A)
|
||||
#define HID_USAGE_KEYBOARD_RETURN ((USAGE)0x28)
|
||||
#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE)0x29)
|
||||
#define HID_USAGE_KEYBOARD_DELETE ((USAGE)0x2A)
|
||||
|
||||
#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE) 0x46)
|
||||
#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE)0x46)
|
||||
|
||||
// and hundreds more...
|
||||
|
||||
|
@ -148,81 +148,81 @@ typedef USHORT USAGE, *PUSAGE;
|
|||
// LED Page (0x08)
|
||||
//
|
||||
|
||||
#define HID_USAGE_LED_NUM_LOCK ((USAGE) 0x01)
|
||||
#define HID_USAGE_LED_CAPS_LOCK ((USAGE) 0x02)
|
||||
#define HID_USAGE_LED_SCROLL_LOCK ((USAGE) 0x03)
|
||||
#define HID_USAGE_LED_COMPOSE ((USAGE) 0x04)
|
||||
#define HID_USAGE_LED_KANA ((USAGE) 0x05)
|
||||
#define HID_USAGE_LED_POWER ((USAGE) 0x06)
|
||||
#define HID_USAGE_LED_SHIFT ((USAGE) 0x07)
|
||||
#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE) 0x08)
|
||||
#define HID_USAGE_LED_MUTE ((USAGE) 0x09)
|
||||
#define HID_USAGE_LED_TONE_ENABLE ((USAGE) 0x0A)
|
||||
#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE) 0x0B)
|
||||
#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE) 0x0C)
|
||||
#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE) 0x0D)
|
||||
#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE) 0x0E)
|
||||
#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE) 0x0F)
|
||||
#define HID_USAGE_LED_REPEAT ((USAGE) 0x10)
|
||||
#define HID_USAGE_LED_STEREO ((USAGE) 0x11)
|
||||
#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE) 0x12)
|
||||
#define HID_USAGE_LED_SPINNING ((USAGE) 0x13)
|
||||
#define HID_USAGE_LED_CAV ((USAGE) 0x14)
|
||||
#define HID_USAGE_LED_CLV ((USAGE) 0x15)
|
||||
#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE) 0x16)
|
||||
#define HID_USAGE_LED_OFF_HOOK ((USAGE) 0x17)
|
||||
#define HID_USAGE_LED_RING ((USAGE) 0x18)
|
||||
#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE) 0x19)
|
||||
#define HID_USAGE_LED_DATA_MODE ((USAGE) 0x1A)
|
||||
#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE) 0x1B)
|
||||
#define HID_USAGE_LED_BATTERY_OK ((USAGE) 0x1C)
|
||||
#define HID_USAGE_LED_BATTERY_LOW ((USAGE) 0x1D)
|
||||
#define HID_USAGE_LED_SPEAKER ((USAGE) 0x1E)
|
||||
#define HID_USAGE_LED_HEAD_SET ((USAGE) 0x1F)
|
||||
#define HID_USAGE_LED_HOLD ((USAGE) 0x20)
|
||||
#define HID_USAGE_LED_MICROPHONE ((USAGE) 0x21)
|
||||
#define HID_USAGE_LED_COVERAGE ((USAGE) 0x22)
|
||||
#define HID_USAGE_LED_NIGHT_MODE ((USAGE) 0x23)
|
||||
#define HID_USAGE_LED_SEND_CALLS ((USAGE) 0x24)
|
||||
#define HID_USAGE_LED_CALL_PICKUP ((USAGE) 0x25)
|
||||
#define HID_USAGE_LED_CONFERENCE ((USAGE) 0x26)
|
||||
#define HID_USAGE_LED_STAND_BY ((USAGE) 0x27)
|
||||
#define HID_USAGE_LED_CAMERA_ON ((USAGE) 0x28)
|
||||
#define HID_USAGE_LED_CAMERA_OFF ((USAGE) 0x29)
|
||||
#define HID_USAGE_LED_ON_LINE ((USAGE) 0x2A)
|
||||
#define HID_USAGE_LED_OFF_LINE ((USAGE) 0x2B)
|
||||
#define HID_USAGE_LED_BUSY ((USAGE) 0x2C)
|
||||
#define HID_USAGE_LED_READY ((USAGE) 0x2D)
|
||||
#define HID_USAGE_LED_PAPER_OUT ((USAGE) 0x2E)
|
||||
#define HID_USAGE_LED_PAPER_JAM ((USAGE) 0x2F)
|
||||
#define HID_USAGE_LED_REMOTE ((USAGE) 0x30)
|
||||
#define HID_USAGE_LED_FORWARD ((USAGE) 0x31)
|
||||
#define HID_USAGE_LED_REVERSE ((USAGE) 0x32)
|
||||
#define HID_USAGE_LED_STOP ((USAGE) 0x33)
|
||||
#define HID_USAGE_LED_REWIND ((USAGE) 0x34)
|
||||
#define HID_USAGE_LED_FAST_FORWARD ((USAGE) 0x35)
|
||||
#define HID_USAGE_LED_PLAY ((USAGE) 0x36)
|
||||
#define HID_USAGE_LED_PAUSE ((USAGE) 0x37)
|
||||
#define HID_USAGE_LED_RECORD ((USAGE) 0x38)
|
||||
#define HID_USAGE_LED_ERROR ((USAGE) 0x39)
|
||||
#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE) 0x3A)
|
||||
#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE) 0x3B)
|
||||
#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE) 0x3C)
|
||||
#define HID_USAGE_LED_INDICATOR_ON ((USAGE) 0x3D)
|
||||
#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE) 0x3E)
|
||||
#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE) 0x3F)
|
||||
#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE) 0x40)
|
||||
#define HID_USAGE_LED_INDICATOR_OFF ((USAGE) 0x41)
|
||||
#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE) 0x42)
|
||||
#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE) 0x43)
|
||||
#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE) 0x44)
|
||||
#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE) 0x45)
|
||||
#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE) 0x46)
|
||||
#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE) 0x47)
|
||||
#define HID_USAGE_LED_RED ((USAGE) 0x48)
|
||||
#define HID_USAGE_LED_GREEN ((USAGE) 0x49)
|
||||
#define HID_USAGE_LED_AMBER ((USAGE) 0x4A)
|
||||
#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE) 0x3B)
|
||||
#define HID_USAGE_LED_NUM_LOCK ((USAGE)0x01)
|
||||
#define HID_USAGE_LED_CAPS_LOCK ((USAGE)0x02)
|
||||
#define HID_USAGE_LED_SCROLL_LOCK ((USAGE)0x03)
|
||||
#define HID_USAGE_LED_COMPOSE ((USAGE)0x04)
|
||||
#define HID_USAGE_LED_KANA ((USAGE)0x05)
|
||||
#define HID_USAGE_LED_POWER ((USAGE)0x06)
|
||||
#define HID_USAGE_LED_SHIFT ((USAGE)0x07)
|
||||
#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE)0x08)
|
||||
#define HID_USAGE_LED_MUTE ((USAGE)0x09)
|
||||
#define HID_USAGE_LED_TONE_ENABLE ((USAGE)0x0A)
|
||||
#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE)0x0B)
|
||||
#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE)0x0C)
|
||||
#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE)0x0D)
|
||||
#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE)0x0E)
|
||||
#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE)0x0F)
|
||||
#define HID_USAGE_LED_REPEAT ((USAGE)0x10)
|
||||
#define HID_USAGE_LED_STEREO ((USAGE)0x11)
|
||||
#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE)0x12)
|
||||
#define HID_USAGE_LED_SPINNING ((USAGE)0x13)
|
||||
#define HID_USAGE_LED_CAV ((USAGE)0x14)
|
||||
#define HID_USAGE_LED_CLV ((USAGE)0x15)
|
||||
#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE)0x16)
|
||||
#define HID_USAGE_LED_OFF_HOOK ((USAGE)0x17)
|
||||
#define HID_USAGE_LED_RING ((USAGE)0x18)
|
||||
#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE)0x19)
|
||||
#define HID_USAGE_LED_DATA_MODE ((USAGE)0x1A)
|
||||
#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE)0x1B)
|
||||
#define HID_USAGE_LED_BATTERY_OK ((USAGE)0x1C)
|
||||
#define HID_USAGE_LED_BATTERY_LOW ((USAGE)0x1D)
|
||||
#define HID_USAGE_LED_SPEAKER ((USAGE)0x1E)
|
||||
#define HID_USAGE_LED_HEAD_SET ((USAGE)0x1F)
|
||||
#define HID_USAGE_LED_HOLD ((USAGE)0x20)
|
||||
#define HID_USAGE_LED_MICROPHONE ((USAGE)0x21)
|
||||
#define HID_USAGE_LED_COVERAGE ((USAGE)0x22)
|
||||
#define HID_USAGE_LED_NIGHT_MODE ((USAGE)0x23)
|
||||
#define HID_USAGE_LED_SEND_CALLS ((USAGE)0x24)
|
||||
#define HID_USAGE_LED_CALL_PICKUP ((USAGE)0x25)
|
||||
#define HID_USAGE_LED_CONFERENCE ((USAGE)0x26)
|
||||
#define HID_USAGE_LED_STAND_BY ((USAGE)0x27)
|
||||
#define HID_USAGE_LED_CAMERA_ON ((USAGE)0x28)
|
||||
#define HID_USAGE_LED_CAMERA_OFF ((USAGE)0x29)
|
||||
#define HID_USAGE_LED_ON_LINE ((USAGE)0x2A)
|
||||
#define HID_USAGE_LED_OFF_LINE ((USAGE)0x2B)
|
||||
#define HID_USAGE_LED_BUSY ((USAGE)0x2C)
|
||||
#define HID_USAGE_LED_READY ((USAGE)0x2D)
|
||||
#define HID_USAGE_LED_PAPER_OUT ((USAGE)0x2E)
|
||||
#define HID_USAGE_LED_PAPER_JAM ((USAGE)0x2F)
|
||||
#define HID_USAGE_LED_REMOTE ((USAGE)0x30)
|
||||
#define HID_USAGE_LED_FORWARD ((USAGE)0x31)
|
||||
#define HID_USAGE_LED_REVERSE ((USAGE)0x32)
|
||||
#define HID_USAGE_LED_STOP ((USAGE)0x33)
|
||||
#define HID_USAGE_LED_REWIND ((USAGE)0x34)
|
||||
#define HID_USAGE_LED_FAST_FORWARD ((USAGE)0x35)
|
||||
#define HID_USAGE_LED_PLAY ((USAGE)0x36)
|
||||
#define HID_USAGE_LED_PAUSE ((USAGE)0x37)
|
||||
#define HID_USAGE_LED_RECORD ((USAGE)0x38)
|
||||
#define HID_USAGE_LED_ERROR ((USAGE)0x39)
|
||||
#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE)0x3A)
|
||||
#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE)0x3B)
|
||||
#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE)0x3C)
|
||||
#define HID_USAGE_LED_INDICATOR_ON ((USAGE)0x3D)
|
||||
#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE)0x3E)
|
||||
#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE)0x3F)
|
||||
#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE)0x40)
|
||||
#define HID_USAGE_LED_INDICATOR_OFF ((USAGE)0x41)
|
||||
#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE)0x42)
|
||||
#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE)0x43)
|
||||
#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE)0x44)
|
||||
#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE)0x45)
|
||||
#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE)0x46)
|
||||
#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE)0x47)
|
||||
#define HID_USAGE_LED_RED ((USAGE)0x48)
|
||||
#define HID_USAGE_LED_GREEN ((USAGE)0x49)
|
||||
#define HID_USAGE_LED_AMBER ((USAGE)0x4A)
|
||||
#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE)0x3B)
|
||||
|
||||
//
|
||||
// Button Page (0x09)
|
||||
|
@ -242,13 +242,13 @@ typedef USHORT USAGE, *PUSAGE;
|
|||
// Telephony Device Page (0x0B)
|
||||
//
|
||||
|
||||
#define HID_USAGE_TELEPHONY_PHONE ((USAGE) 0x01)
|
||||
#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE) 0x02)
|
||||
#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE) 0x03)
|
||||
#define HID_USAGE_TELEPHONY_HANDSET ((USAGE) 0x04)
|
||||
#define HID_USAGE_TELEPHONY_HEADSET ((USAGE) 0x05)
|
||||
#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE) 0x06)
|
||||
#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE) 0x07)
|
||||
#define HID_USAGE_TELEPHONY_PHONE ((USAGE)0x01)
|
||||
#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE)0x02)
|
||||
#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE)0x03)
|
||||
#define HID_USAGE_TELEPHONY_HANDSET ((USAGE)0x04)
|
||||
#define HID_USAGE_TELEPHONY_HEADSET ((USAGE)0x05)
|
||||
#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE)0x06)
|
||||
#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE)0x07)
|
||||
|
||||
// BUGBUG defined in ntstatus.h
|
||||
#ifndef FACILITY_HID_ERROR_CODE
|
||||
|
@ -256,190 +256,198 @@ typedef USHORT USAGE, *PUSAGE;
|
|||
#endif
|
||||
|
||||
#define HIDP_ERROR_CODES(SEV, CODE) \
|
||||
((NTSTATUS)(((SEV) << 28) | (FACILITY_HID_ERROR_CODE << 16) | (CODE)))
|
||||
((NTSTATUS)(((SEV) << 28) | (FACILITY_HID_ERROR_CODE << 16) | (CODE)))
|
||||
|
||||
#define HIDP_STATUS_SUCCESS (HIDP_ERROR_CODES(0x0,0))
|
||||
#define HIDP_STATUS_NULL (HIDP_ERROR_CODES(0x8,1))
|
||||
#define HIDP_STATUS_INVALID_PREPARSED_DATA (HIDP_ERROR_CODES(0xC,1))
|
||||
#define HIDP_STATUS_INVALID_REPORT_TYPE (HIDP_ERROR_CODES(0xC,2))
|
||||
#define HIDP_STATUS_INVALID_REPORT_LENGTH (HIDP_ERROR_CODES(0xC,3))
|
||||
#define HIDP_STATUS_USAGE_NOT_FOUND (HIDP_ERROR_CODES(0xC,4))
|
||||
#define HIDP_STATUS_VALUE_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,5))
|
||||
#define HIDP_STATUS_BAD_LOG_PHY_VALUES (HIDP_ERROR_CODES(0xC,6))
|
||||
#define HIDP_STATUS_BUFFER_TOO_SMALL (HIDP_ERROR_CODES(0xC,7))
|
||||
#define HIDP_STATUS_INTERNAL_ERROR (HIDP_ERROR_CODES(0xC,8))
|
||||
#define HIDP_STATUS_I8242_TRANS_UNKNOWN (HIDP_ERROR_CODES(0xC,9))
|
||||
#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID (HIDP_ERROR_CODES(0xC,0xA))
|
||||
#define HIDP_STATUS_NOT_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xB))
|
||||
#define HIDP_STATUS_IS_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xC))
|
||||
#define HIDP_STATUS_DATA_INDEX_NOT_FOUND (HIDP_ERROR_CODES(0xC,0xD))
|
||||
#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,0xE))
|
||||
#define HIDP_STATUS_BUTTON_NOT_PRESSED (HIDP_ERROR_CODES(0xC,0xF))
|
||||
#define HIDP_STATUS_REPORT_DOES_NOT_EXIST (HIDP_ERROR_CODES(0xC,0x10))
|
||||
#define HIDP_STATUS_NOT_IMPLEMENTED (HIDP_ERROR_CODES(0xC,0x20))
|
||||
#define HIDP_STATUS_SUCCESS (HIDP_ERROR_CODES(0x0, 0))
|
||||
#define HIDP_STATUS_NULL (HIDP_ERROR_CODES(0x8, 1))
|
||||
#define HIDP_STATUS_INVALID_PREPARSED_DATA (HIDP_ERROR_CODES(0xC, 1))
|
||||
#define HIDP_STATUS_INVALID_REPORT_TYPE (HIDP_ERROR_CODES(0xC, 2))
|
||||
#define HIDP_STATUS_INVALID_REPORT_LENGTH (HIDP_ERROR_CODES(0xC, 3))
|
||||
#define HIDP_STATUS_USAGE_NOT_FOUND (HIDP_ERROR_CODES(0xC, 4))
|
||||
#define HIDP_STATUS_VALUE_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC, 5))
|
||||
#define HIDP_STATUS_BAD_LOG_PHY_VALUES (HIDP_ERROR_CODES(0xC, 6))
|
||||
#define HIDP_STATUS_BUFFER_TOO_SMALL (HIDP_ERROR_CODES(0xC, 7))
|
||||
#define HIDP_STATUS_INTERNAL_ERROR (HIDP_ERROR_CODES(0xC, 8))
|
||||
#define HIDP_STATUS_I8242_TRANS_UNKNOWN (HIDP_ERROR_CODES(0xC, 9))
|
||||
#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID (HIDP_ERROR_CODES(0xC, 0xA))
|
||||
#define HIDP_STATUS_NOT_VALUE_ARRAY (HIDP_ERROR_CODES(0xC, 0xB))
|
||||
#define HIDP_STATUS_IS_VALUE_ARRAY (HIDP_ERROR_CODES(0xC, 0xC))
|
||||
#define HIDP_STATUS_DATA_INDEX_NOT_FOUND (HIDP_ERROR_CODES(0xC, 0xD))
|
||||
#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC, 0xE))
|
||||
#define HIDP_STATUS_BUTTON_NOT_PRESSED (HIDP_ERROR_CODES(0xC, 0xF))
|
||||
#define HIDP_STATUS_REPORT_DOES_NOT_EXIST (HIDP_ERROR_CODES(0xC, 0x10))
|
||||
#define HIDP_STATUS_NOT_IMPLEMENTED (HIDP_ERROR_CODES(0xC, 0x20))
|
||||
|
||||
typedef enum _HIDP_REPORT_TYPE
|
||||
{
|
||||
HidP_Input,
|
||||
HidP_Output,
|
||||
HidP_Feature
|
||||
HidP_Input,
|
||||
HidP_Output,
|
||||
HidP_Feature
|
||||
} HIDP_REPORT_TYPE;
|
||||
|
||||
typedef struct _USAGE_AND_PAGE
|
||||
{
|
||||
USAGE Usage;
|
||||
USAGE UsagePage;
|
||||
USAGE Usage;
|
||||
USAGE UsagePage;
|
||||
} USAGE_AND_PAGE, *PUSAGE_AND_PAGE;
|
||||
|
||||
typedef struct _HIDP_BUTTON_CAPS
|
||||
{
|
||||
USAGE UsagePage;
|
||||
UCHAR ReportID;
|
||||
BOOLEAN IsAlias;
|
||||
USAGE UsagePage;
|
||||
UCHAR ReportID;
|
||||
BOOLEAN IsAlias;
|
||||
|
||||
USHORT BitField;
|
||||
USHORT LinkCollection; // A unique internal index pointer
|
||||
USHORT BitField;
|
||||
USHORT LinkCollection; // A unique internal index pointer
|
||||
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
|
||||
BOOLEAN IsRange;
|
||||
BOOLEAN IsStringRange;
|
||||
BOOLEAN IsDesignatorRange;
|
||||
BOOLEAN IsAbsolute;
|
||||
BOOLEAN IsRange;
|
||||
BOOLEAN IsStringRange;
|
||||
BOOLEAN IsDesignatorRange;
|
||||
BOOLEAN IsAbsolute;
|
||||
|
||||
ULONG Reserved[10];
|
||||
union {
|
||||
struct {
|
||||
USAGE UsageMin, UsageMax;
|
||||
USHORT StringMin, StringMax;
|
||||
USHORT DesignatorMin, DesignatorMax;
|
||||
USHORT DataIndexMin, DataIndexMax;
|
||||
} Range;
|
||||
struct {
|
||||
USAGE Usage, Reserved1;
|
||||
USHORT StringIndex, Reserved2;
|
||||
USHORT DesignatorIndex, Reserved3;
|
||||
USHORT DataIndex, Reserved4;
|
||||
} NotRange;
|
||||
};
|
||||
ULONG Reserved[10];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USAGE UsageMin, UsageMax;
|
||||
USHORT StringMin, StringMax;
|
||||
USHORT DesignatorMin, DesignatorMax;
|
||||
USHORT DataIndexMin, DataIndexMax;
|
||||
} Range;
|
||||
struct
|
||||
{
|
||||
USAGE Usage, Reserved1;
|
||||
USHORT StringIndex, Reserved2;
|
||||
USHORT DesignatorIndex, Reserved3;
|
||||
USHORT DataIndex, Reserved4;
|
||||
} NotRange;
|
||||
};
|
||||
|
||||
} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS;
|
||||
|
||||
|
||||
typedef struct _HIDP_VALUE_CAPS
|
||||
{
|
||||
USAGE UsagePage;
|
||||
UCHAR ReportID;
|
||||
BOOLEAN IsAlias;
|
||||
USAGE UsagePage;
|
||||
UCHAR ReportID;
|
||||
BOOLEAN IsAlias;
|
||||
|
||||
USHORT BitField;
|
||||
USHORT LinkCollection; // A unique internal index pointer
|
||||
USHORT BitField;
|
||||
USHORT LinkCollection; // A unique internal index pointer
|
||||
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
|
||||
BOOLEAN IsRange;
|
||||
BOOLEAN IsStringRange;
|
||||
BOOLEAN IsDesignatorRange;
|
||||
BOOLEAN IsAbsolute;
|
||||
BOOLEAN IsRange;
|
||||
BOOLEAN IsStringRange;
|
||||
BOOLEAN IsDesignatorRange;
|
||||
BOOLEAN IsAbsolute;
|
||||
|
||||
BOOLEAN HasNull; // Does this channel have a null report union
|
||||
UCHAR Reserved;
|
||||
USHORT BitSize; // How many bits are devoted to this value?
|
||||
BOOLEAN HasNull; // Does this channel have a null report union
|
||||
UCHAR Reserved;
|
||||
USHORT BitSize; // How many bits are devoted to this value?
|
||||
|
||||
USHORT ReportCount; // See Note below. Usually set to 1.
|
||||
USHORT Reserved2[5];
|
||||
USHORT ReportCount; // See Note below. Usually set to 1.
|
||||
USHORT Reserved2[5];
|
||||
|
||||
ULONG UnitsExp;
|
||||
ULONG Units;
|
||||
ULONG UnitsExp;
|
||||
ULONG Units;
|
||||
|
||||
LONG LogicalMin, LogicalMax;
|
||||
LONG PhysicalMin, PhysicalMax;
|
||||
LONG LogicalMin, LogicalMax;
|
||||
LONG PhysicalMin, PhysicalMax;
|
||||
|
||||
union {
|
||||
struct {
|
||||
USAGE UsageMin, UsageMax;
|
||||
USHORT StringMin, StringMax;
|
||||
USHORT DesignatorMin, DesignatorMax;
|
||||
USHORT DataIndexMin, DataIndexMax;
|
||||
} Range;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USAGE UsageMin, UsageMax;
|
||||
USHORT StringMin, StringMax;
|
||||
USHORT DesignatorMin, DesignatorMax;
|
||||
USHORT DataIndexMin, DataIndexMax;
|
||||
} Range;
|
||||
|
||||
struct {
|
||||
USAGE Usage, Reserved1;
|
||||
USHORT StringIndex, Reserved2;
|
||||
USHORT DesignatorIndex, Reserved3;
|
||||
USHORT DataIndex, Reserved4;
|
||||
} NotRange;
|
||||
};
|
||||
struct
|
||||
{
|
||||
USAGE Usage, Reserved1;
|
||||
USHORT StringIndex, Reserved2;
|
||||
USHORT DesignatorIndex, Reserved3;
|
||||
USHORT DataIndex, Reserved4;
|
||||
} NotRange;
|
||||
};
|
||||
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
|
||||
|
||||
typedef struct _HIDD_ATTRIBUTES {
|
||||
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
|
||||
typedef struct _HIDD_ATTRIBUTES
|
||||
{
|
||||
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
|
||||
|
||||
//
|
||||
// Vendor ids of this hid device
|
||||
//
|
||||
USHORT VendorID;
|
||||
USHORT ProductID;
|
||||
USHORT VersionNumber;
|
||||
//
|
||||
// Vendor ids of this hid device
|
||||
//
|
||||
USHORT VendorID;
|
||||
USHORT ProductID;
|
||||
USHORT VersionNumber;
|
||||
|
||||
//
|
||||
// Additional fields will be added to the end of this structure.
|
||||
//
|
||||
//
|
||||
// Additional fields will be added to the end of this structure.
|
||||
//
|
||||
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
|
||||
|
||||
typedef PUCHAR PHIDP_REPORT_DESCRIPTOR;
|
||||
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
|
||||
typedef PUCHAR PHIDP_REPORT_DESCRIPTOR;
|
||||
typedef struct _HIDP_PREPARSED_DATA* PHIDP_PREPARSED_DATA;
|
||||
|
||||
|
||||
typedef struct _HIDP_CAPS
|
||||
{
|
||||
USAGE Usage;
|
||||
USAGE UsagePage;
|
||||
USHORT InputReportByteLength;
|
||||
USHORT OutputReportByteLength;
|
||||
USHORT FeatureReportByteLength;
|
||||
USHORT Reserved[17];
|
||||
USAGE Usage;
|
||||
USAGE UsagePage;
|
||||
USHORT InputReportByteLength;
|
||||
USHORT OutputReportByteLength;
|
||||
USHORT FeatureReportByteLength;
|
||||
USHORT Reserved[17];
|
||||
|
||||
USHORT NumberLinkCollectionNodes;
|
||||
USHORT NumberLinkCollectionNodes;
|
||||
|
||||
USHORT NumberInputButtonCaps;
|
||||
USHORT NumberInputValueCaps;
|
||||
USHORT NumberInputDataIndices;
|
||||
USHORT NumberInputButtonCaps;
|
||||
USHORT NumberInputValueCaps;
|
||||
USHORT NumberInputDataIndices;
|
||||
|
||||
USHORT NumberOutputButtonCaps;
|
||||
USHORT NumberOutputValueCaps;
|
||||
USHORT NumberOutputDataIndices;
|
||||
USHORT NumberOutputButtonCaps;
|
||||
USHORT NumberOutputValueCaps;
|
||||
USHORT NumberOutputDataIndices;
|
||||
|
||||
USHORT NumberFeatureButtonCaps;
|
||||
USHORT NumberFeatureValueCaps;
|
||||
USHORT NumberFeatureDataIndices;
|
||||
USHORT NumberFeatureButtonCaps;
|
||||
USHORT NumberFeatureValueCaps;
|
||||
USHORT NumberFeatureDataIndices;
|
||||
} HIDP_CAPS, *PHIDP_CAPS;
|
||||
|
||||
typedef struct _HIDP_DATA
|
||||
{
|
||||
USHORT DataIndex;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
ULONG RawValue; // for values
|
||||
BOOLEAN On; // for buttons MUST BE TRUE for buttons.
|
||||
};
|
||||
USHORT DataIndex;
|
||||
USHORT Reserved;
|
||||
union
|
||||
{
|
||||
ULONG RawValue; // for values
|
||||
BOOLEAN On; // for buttons MUST BE TRUE for buttons.
|
||||
};
|
||||
} HIDP_DATA, *PHIDP_DATA;
|
||||
|
||||
typedef BOOLEAN(__stdcall *_HidD_GetAttributes) (HANDLE HidDeviceObject, HIDD_ATTRIBUTES *Attributes);
|
||||
typedef void(__stdcall *_HidD_GetHidGuid) (GUID* HidGuid);
|
||||
typedef BOOLEAN(__stdcall *_HidD_GetPreparsedData) (HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA *PreparsedData);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetCaps) (PHIDP_PREPARSED_DATA PreparsedData, HIDP_CAPS *caps);
|
||||
typedef BOOLEAN(__stdcall *_HidD_FreePreparsedData) (PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef BOOLEAN(__stdcall *_HidD_GetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
typedef BOOLEAN(__stdcall *_HidD_SetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetSpecificButtonCaps) (HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetButtonCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetUsages)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE *UsageList, ULONG *UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetValueCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall *_HidP_GetUsageValue)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
typedef BOOLEAN (__stdcall *_HidD_GetProductString)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
|
||||
typedef BOOLEAN(__stdcall* _HidD_GetAttributes)(HANDLE HidDeviceObject, HIDD_ATTRIBUTES* Attributes);
|
||||
typedef void(__stdcall* _HidD_GetHidGuid)(GUID* HidGuid);
|
||||
typedef BOOLEAN(__stdcall* _HidD_GetPreparsedData)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA* PreparsedData);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetCaps)(PHIDP_PREPARSED_DATA PreparsedData, HIDP_CAPS* caps);
|
||||
typedef BOOLEAN(__stdcall* _HidD_FreePreparsedData)(PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef BOOLEAN(__stdcall* _HidD_GetFeature)(HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
typedef BOOLEAN(__stdcall* _HidD_SetFeature)(HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetSpecificButtonCaps)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetButtonCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetUsages)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE* UsageList, ULONG* UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetValueCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(__stdcall* _HidP_GetUsageValue)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
typedef BOOLEAN(__stdcall* _HidD_GetProductString)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
|
||||
|
||||
//#define HidP_GetButtonCaps(_Type_, _Caps_, _Len_, _Data_) \
|
||||
// HidP_GetSpecificButtonCaps(_Type_, 0, 0, 0, _Caps_, _Len_, _Data_)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -51,7 +51,7 @@
|
|||
#ifdef _WIN32
|
||||
// VC6 "identifier was truncated to '255' characters in the debug information"
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1300)
|
||||
#pragma warning(disable: 4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
// Prevent compile time warnings for deprecation
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
@ -63,208 +63,221 @@
|
|||
#include <wchar.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define INI_TOKEN_A_ANSI "\a" // I.E. Item1;Item2;Item3 - '\a' used in place of ';'
|
||||
#define INI_TOKEN_B_ANSI "\b" // I.E. Item1,Item1b;Item2,Item2b;Item3,Item3b - '\b' used in place of ','
|
||||
#define INI_EMPTY_ANSI "*" // Used to indicate empty value in token string. I.E. *;Item2;*;Item3;
|
||||
#define INI_TOKEN_A_ANSI "\a" // I.E. Item1;Item2;Item3 - '\a' used in place of ';'
|
||||
#define INI_TOKEN_B_ANSI "\b" // I.E. Item1,Item1b;Item2,Item2b;Item3,Item3b - '\b' used in place of ','
|
||||
#define INI_EMPTY_ANSI "*" // Used to indicate empty value in token string. I.E. *;Item2;*;Item3;
|
||||
|
||||
class CIniFileA
|
||||
{
|
||||
public:
|
||||
static const char* const LF;
|
||||
public:
|
||||
CIniFileA();
|
||||
~CIniFileA();
|
||||
|
||||
// Used to save the data back to the file or your choice
|
||||
bool Save( const std::string& fileName );
|
||||
|
||||
// Save data to an output stream
|
||||
void Save( std::ostream& output );
|
||||
|
||||
// Loads the Reads the data in the ini file into the IniFile object
|
||||
bool Load( const std::string& fileName , bool bMerge = false );
|
||||
|
||||
// Load data from an input stream
|
||||
void Load( std::istream& input , bool bMerge = false );
|
||||
static const char* const LF;
|
||||
|
||||
public:
|
||||
class CIniMergeA
|
||||
{
|
||||
public:
|
||||
explicit CIniMergeA(CIniFileA& ini):_ini(ini) {}
|
||||
std::istream &operator()(std::istream& input) const
|
||||
{
|
||||
_ini.Load( input , true );
|
||||
return input;
|
||||
}
|
||||
private:
|
||||
CIniFileA& _ini;
|
||||
};
|
||||
CIniFileA();
|
||||
~CIniFileA();
|
||||
|
||||
// Used to save the data back to the file or your choice
|
||||
bool Save(const std::string& fileName);
|
||||
|
||||
// Save data to an output stream
|
||||
void Save(std::ostream& output);
|
||||
|
||||
// Loads the Reads the data in the ini file into the IniFile object
|
||||
bool Load(const std::string& fileName, bool bMerge = false);
|
||||
|
||||
// Load data from an input stream
|
||||
void Load(std::istream& input, bool bMerge = false);
|
||||
|
||||
public:
|
||||
class CIniMergeA
|
||||
{
|
||||
public:
|
||||
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
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
struct ci_less_a;
|
||||
struct ci_less_a;
|
||||
#endif
|
||||
#endif
|
||||
class CIniSectionA
|
||||
{
|
||||
friend class CIniFileA; // Allow CIniFileA to create sections
|
||||
class CIniSectionA
|
||||
{
|
||||
friend class CIniFileA; // Allow CIniFileA to create sections
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
friend struct ci_less_a;
|
||||
friend struct ci_less_a;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
public:
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
struct ci_less_a;
|
||||
struct ci_less_a;
|
||||
#endif
|
||||
#endif
|
||||
class CIniKeyA
|
||||
{
|
||||
friend class CIniSectionA; // Allow CIniSectionA to create keys
|
||||
class CIniKeyA
|
||||
{
|
||||
friend class CIniSectionA; // Allow CIniSectionA to create keys
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
friend struct ci_less_a;
|
||||
friend struct ci_less_a;
|
||||
#endif
|
||||
#endif
|
||||
private: // CIniFileA acts as a class factory for CIniSectionA Objects
|
||||
CIniKeyA( CIniSectionA* pSection , const std::string& sKeyName );
|
||||
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 );
|
||||
// Returns the value of the key
|
||||
std::string GetValue() const;
|
||||
// Sets the key name, returns true on success, fails if the section
|
||||
// name sKeyName already exists
|
||||
bool SetKeyName( std::string sKeyName );
|
||||
// Returns the name of the Key
|
||||
std::string GetKeyName() const;
|
||||
private:
|
||||
// Pointer to the parent CIniSectionA
|
||||
CIniSectionA* m_pSection;
|
||||
// Name of the Key
|
||||
std::string m_sKeyName;
|
||||
// Value associated
|
||||
std::string m_sValue;
|
||||
}; // End of CIniKeyA
|
||||
// Typedef of set of CIniKeyA pointers
|
||||
struct ci_less_a
|
||||
{
|
||||
bool operator() (const CIniKeyA* s1, const CIniKeyA* s2) const
|
||||
{
|
||||
private: // CIniFileA acts as a class factory for CIniSectionA Objects
|
||||
CIniKeyA(CIniSectionA* pSection, const std::string& sKeyName);
|
||||
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);
|
||||
// Returns the value of the key
|
||||
std::string GetValue() const;
|
||||
// Sets the key name, returns true on success, fails if the section
|
||||
// name sKeyName already exists
|
||||
bool SetKeyName(std::string sKeyName);
|
||||
// Returns the name of the Key
|
||||
std::string GetKeyName() const;
|
||||
|
||||
private:
|
||||
// Pointer to the parent CIniSectionA
|
||||
CIniSectionA* m_pSection;
|
||||
// Name of the Key
|
||||
std::string m_sKeyName;
|
||||
// Value associated
|
||||
std::string m_sValue;
|
||||
}; // End of CIniKeyA
|
||||
// Typedef of set of CIniKeyA pointers
|
||||
struct ci_less_a
|
||||
{
|
||||
bool operator()(const CIniKeyA* s1, const CIniKeyA* s2) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return strcasecmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
return strcasecmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
#else
|
||||
return _stricmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
return _stricmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<CIniKeyA*,ci_less_a> KeyIndexA;
|
||||
typedef std::set<CIniKeyA*, ci_less_a> KeyIndexA;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Added for VC6 Support
|
||||
// Added for VC6 Support
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1300)
|
||||
friend class CIniKeyA;
|
||||
friend class CIniKeyA;
|
||||
#endif
|
||||
#endif
|
||||
private: // CIniSectionA acts as a class factory for CIniKeyA Objects
|
||||
CIniSectionA( CIniFileA* pIniFile , const std::string& sSectionName );
|
||||
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 );
|
||||
// Removes a single key by pointer
|
||||
void RemoveKey( CIniKeyA* pKey );
|
||||
// Removes a single key by string
|
||||
void RemoveKey( std::string sKey );
|
||||
// Removes all the keys in the section
|
||||
void RemoveAllKeys( );
|
||||
// Returns a CIniKeyA pointer to the key by name, NULL if it was not found
|
||||
CIniKeyA* GetKey( std::string sKeyName ) const;
|
||||
// Returns all keys in the section by KeyIndex only to be used for enumeration
|
||||
const KeyIndexA& GetKeys() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::string GetKeyValue( std::string sKey ) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue( std::string sKey, const std::string& sValue );
|
||||
// Sets the section name, returns true on success, fails if the section
|
||||
// name sSectionName already exists
|
||||
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;
|
||||
// Name of the section
|
||||
std::string m_sSectionName;
|
||||
// List of CIniKeyA pointers ( Keys in the section )
|
||||
KeyIndexA m_keys;
|
||||
}; // End of CIniSectionA
|
||||
// Typedef of a List of CIniSectionA pointers
|
||||
struct ci_less_a
|
||||
{
|
||||
bool operator() (const CIniSectionA* s1, const CIniSectionA* s2) const
|
||||
{
|
||||
private: // CIniSectionA acts as a class factory for CIniKeyA Objects
|
||||
CIniSectionA(CIniFileA* pIniFile, const std::string& sSectionName);
|
||||
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);
|
||||
// Removes a single key by pointer
|
||||
void RemoveKey(CIniKeyA* pKey);
|
||||
// Removes a single key by string
|
||||
void RemoveKey(std::string sKey);
|
||||
// Removes all the keys in the section
|
||||
void RemoveAllKeys();
|
||||
// Returns a CIniKeyA pointer to the key by name, NULL if it was not found
|
||||
CIniKeyA* GetKey(std::string sKeyName) const;
|
||||
// Returns all keys in the section by KeyIndex only to be used for enumeration
|
||||
const KeyIndexA& GetKeys() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::string GetKeyValue(std::string sKey) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue(std::string sKey, const std::string& sValue);
|
||||
// Sets the section name, returns true on success, fails if the section
|
||||
// name sSectionName already exists
|
||||
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;
|
||||
// Name of the section
|
||||
std::string m_sSectionName;
|
||||
// List of CIniKeyA pointers ( Keys in the section )
|
||||
KeyIndexA m_keys;
|
||||
}; // End of CIniSectionA
|
||||
// Typedef of a List of CIniSectionA pointers
|
||||
struct ci_less_a
|
||||
{
|
||||
bool operator()(const CIniSectionA* s1, const CIniSectionA* s2) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return strcasecmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
return strcasecmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
#else
|
||||
return _stricmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
return _stricmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<CIniSectionA*,ci_less_a> SecIndexA;
|
||||
typedef std::set<CIniSectionA*, ci_less_a> SecIndexA;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Added for VC6 Support
|
||||
// Added for VC6 Support
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1300)
|
||||
friend class CIniSectionA;
|
||||
friend class CIniSectionA;
|
||||
#endif
|
||||
#endif
|
||||
public:
|
||||
// Adds a section to the CIniFileA object, returns a CIniFileA pointer to the new or existing object
|
||||
CIniSectionA* AddSection( std::string sSection );
|
||||
// Removes section by pointer
|
||||
void RemoveSection( CIniSectionA* pSection );
|
||||
// Removes a section by its name sSection
|
||||
void RemoveSection( std::string sSection );
|
||||
// Removes all existing sections
|
||||
void RemoveAllSections( );
|
||||
// Returns a CIniSectionA* to the section by name, NULL if it was not found
|
||||
CIniSectionA* GetSection( std::string sSection ) const;
|
||||
// Returns all sections in the inifile by SecIndex, only to be used for enumeration (DO NOT KEEP THE REF OR TRY TO DELETE STUFF!)
|
||||
const SecIndexA& GetSections() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::string GetKeyValue( const std::string& sSection, const std::string& sKey ) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue( const std::string& sSection, const std::string& sKey, const std::string& sValue );
|
||||
// Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSectionName
|
||||
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);
|
||||
// Adds a section to the CIniFileA object, returns a CIniFileA pointer to the new or existing object
|
||||
CIniSectionA* AddSection(std::string sSection);
|
||||
// Removes section by pointer
|
||||
void RemoveSection(CIniSectionA* pSection);
|
||||
// Removes a section by its name sSection
|
||||
void RemoveSection(std::string sSection);
|
||||
// Removes all existing sections
|
||||
void RemoveAllSections();
|
||||
// Returns a CIniSectionA* to the section by name, NULL if it was not found
|
||||
CIniSectionA* GetSection(std::string sSection) const;
|
||||
// Returns all sections in the inifile by SecIndex, only to be used for enumeration (DO NOT KEEP THE REF OR TRY TO DELETE STUFF!)
|
||||
const SecIndexA& GetSections() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::string GetKeyValue(const std::string& sSection, const std::string& sKey) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue(const std::string& sSection, const std::string& sKey, const std::string& sValue);
|
||||
// Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSectionName
|
||||
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 );
|
||||
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
|
||||
// List of CIniSectionA pointers ( List of sections in the class )
|
||||
SecIndexA m_sections;
|
||||
CIniFileA(const CIniFileA&); // No Copy
|
||||
CIniFileA& operator=(const CIniFileA&); // No Copy
|
||||
// List of CIniSectionA pointers ( List of sections in the class )
|
||||
SecIndexA m_sections;
|
||||
}; // End of CIniFileA
|
||||
|
||||
// Basic typedefs for ease of use
|
||||
|
@ -287,207 +300,220 @@ std::istream& operator>>(std::istream& input, CIniMergeA merger);
|
|||
|
||||
// Unicode Class Definition
|
||||
|
||||
#define INI_TOKEN_A_UNICODE L"\a" // I.E. Item1;Item2;Item3 - '\a' used in place of ';'
|
||||
#define INI_TOKEN_B_UNICODE L"\b" // I.E. Item1,Item1b;Item2,Item2b;Item3,Item3b - '\b' used in place of ','
|
||||
#define INI_EMPTY_UNICODE L"*" // Used to indicate empty value in token string. I.E. *;Item2;*;Item3;
|
||||
#define INI_TOKEN_A_UNICODE L"\a" // I.E. Item1;Item2;Item3 - '\a' used in place of ';'
|
||||
#define INI_TOKEN_B_UNICODE L"\b" // I.E. Item1,Item1b;Item2,Item2b;Item3,Item3b - '\b' used in place of ','
|
||||
#define INI_EMPTY_UNICODE L"*" // Used to indicate empty value in token string. I.E. *;Item2;*;Item3;
|
||||
|
||||
class CIniFileW
|
||||
{
|
||||
public:
|
||||
static const wchar_t* const LF;
|
||||
public:
|
||||
CIniFileW();
|
||||
~CIniFileW();
|
||||
|
||||
// Used to save the data back to the file or your choice
|
||||
bool Save( const std::wstring& fileName );
|
||||
|
||||
// Save data to an output stream
|
||||
void Save( std::wostream& output );
|
||||
|
||||
// Loads the Reads the data in the ini file into the IniFile object
|
||||
bool Load( const std::wstring& fileName , bool bMerge = false );
|
||||
|
||||
// Load data from an input stream
|
||||
void Load( std::wistream& input , bool bMerge = false );
|
||||
static const wchar_t* const LF;
|
||||
|
||||
public:
|
||||
class CIniMergeW
|
||||
{
|
||||
public:
|
||||
explicit CIniMergeW(CIniFileW& ini):_ini(ini) {}
|
||||
std::wistream &operator()(std::wistream& input) const
|
||||
{
|
||||
_ini.Load( input , true );
|
||||
return input;
|
||||
}
|
||||
private:
|
||||
CIniFileW& _ini;
|
||||
};
|
||||
CIniFileW();
|
||||
~CIniFileW();
|
||||
|
||||
// Used to save the data back to the file or your choice
|
||||
bool Save(const std::wstring& fileName);
|
||||
|
||||
// Save data to an output stream
|
||||
void Save(std::wostream& output);
|
||||
|
||||
// Loads the Reads the data in the ini file into the IniFile object
|
||||
bool Load(const std::wstring& fileName, bool bMerge = false);
|
||||
|
||||
// Load data from an input stream
|
||||
void Load(std::wistream& input, bool bMerge = false);
|
||||
|
||||
public:
|
||||
class CIniMergeW
|
||||
{
|
||||
public:
|
||||
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
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
struct ci_less_w;
|
||||
struct ci_less_w;
|
||||
#endif
|
||||
#endif
|
||||
class CIniSectionW
|
||||
{
|
||||
friend class CIniFileW; // Allow CIniFileW to create sections
|
||||
class CIniSectionW
|
||||
{
|
||||
friend class CIniFileW; // Allow CIniFileW to create sections
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
friend struct ci_less_w;
|
||||
friend struct ci_less_w;
|
||||
#endif
|
||||
#endif
|
||||
public:
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
struct ci_less_w;
|
||||
struct ci_less_w;
|
||||
#endif
|
||||
#endif
|
||||
class CIniKeyW
|
||||
{
|
||||
friend class CIniSectionW; // Allow CIniSectionW to create keys
|
||||
class CIniKeyW
|
||||
{
|
||||
friend class CIniSectionW; // Allow CIniSectionW to create keys
|
||||
#ifdef _WIN32
|
||||
// Added for versions earlier than VS2008
|
||||
// Added for versions earlier than VS2008
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
friend struct ci_less_w;
|
||||
friend struct ci_less_w;
|
||||
#endif
|
||||
#endif
|
||||
private: // CIniFileW acts as a class factory for CIniSectionW Objects
|
||||
CIniKeyW( CIniSectionW* pSection , const std::wstring& sKeyName );
|
||||
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 );
|
||||
// Returns the value of the key
|
||||
std::wstring GetValue() const;
|
||||
// Sets the key name, returns true on success, fails if the section
|
||||
// name sKeyName already exists
|
||||
bool SetKeyName( std::wstring sKeyName );
|
||||
// Returns the name of the Key
|
||||
std::wstring GetKeyName() const;
|
||||
private:
|
||||
// Pointer to the parent CIniSectionW
|
||||
CIniSectionW* m_pSection;
|
||||
// Name of the Key
|
||||
std::wstring m_sKeyName;
|
||||
// Value associated
|
||||
std::wstring m_sValue;
|
||||
}; // End of CIniKeyW
|
||||
// Typedef of set of CIniKeyW pointers
|
||||
struct ci_less_w
|
||||
{
|
||||
bool operator() (const CIniKeyW* s1, const CIniKeyW* s2) const
|
||||
{
|
||||
private: // CIniFileW acts as a class factory for CIniSectionW Objects
|
||||
CIniKeyW(CIniSectionW* pSection, const std::wstring& sKeyName);
|
||||
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);
|
||||
// Returns the value of the key
|
||||
std::wstring GetValue() const;
|
||||
// Sets the key name, returns true on success, fails if the section
|
||||
// name sKeyName already exists
|
||||
bool SetKeyName(std::wstring sKeyName);
|
||||
// Returns the name of the Key
|
||||
std::wstring GetKeyName() const;
|
||||
|
||||
private:
|
||||
// Pointer to the parent CIniSectionW
|
||||
CIniSectionW* m_pSection;
|
||||
// Name of the Key
|
||||
std::wstring m_sKeyName;
|
||||
// Value associated
|
||||
std::wstring m_sValue;
|
||||
}; // End of CIniKeyW
|
||||
// Typedef of set of CIniKeyW pointers
|
||||
struct ci_less_w
|
||||
{
|
||||
bool operator()(const CIniKeyW* s1, const CIniKeyW* s2) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return wcscasecmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
return wcscasecmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
#else
|
||||
return _wcsicmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
return _wcsicmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<CIniKeyW*,ci_less_w> KeyIndexW;
|
||||
typedef std::set<CIniKeyW*, ci_less_w> KeyIndexW;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Added for VC6 Support
|
||||
// Added for VC6 Support
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1300)
|
||||
friend class CIniKeyW;
|
||||
friend class CIniKeyW;
|
||||
#endif
|
||||
#endif
|
||||
private: // CIniSectionW acts as a class factory for CIniKeyW Objects
|
||||
CIniSectionW( CIniFileW* pIniFile , const std::wstring& sSectionName );
|
||||
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 );
|
||||
// Removes a single key by pointer
|
||||
void RemoveKey( CIniKeyW* pKey );
|
||||
// Removes a single key by string
|
||||
void RemoveKey( std::wstring sKey );
|
||||
// Removes all the keys in the section
|
||||
void RemoveAllKeys( );
|
||||
// Returns a CIniKeyW pointer to the key by name, NULL if it was not found
|
||||
CIniKeyW* GetKey( std::wstring sKeyName ) const;
|
||||
// Returns all keys in the section by KeyIndex only to be used for enumeration
|
||||
const KeyIndexW& GetKeys() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::wstring GetKeyValue( std::wstring sKey ) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue( std::wstring sKey, const std::wstring& sValue );
|
||||
// Sets the section name, returns true on success, fails if the section
|
||||
// name sSectionName already exists
|
||||
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;
|
||||
// Name of the section
|
||||
std::wstring m_sSectionName;
|
||||
// List of CIniKeyW pointers ( Keys in the section )
|
||||
KeyIndexW m_keys;
|
||||
}; // End of CIniSectionW
|
||||
// Typedef of a List of CIniSectionW pointers
|
||||
struct ci_less_w
|
||||
{
|
||||
bool operator() (const CIniSectionW* s1, const CIniSectionW* s2) const
|
||||
{
|
||||
private: // CIniSectionW acts as a class factory for CIniKeyW Objects
|
||||
CIniSectionW(CIniFileW* pIniFile, const std::wstring& sSectionName);
|
||||
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);
|
||||
// Removes a single key by pointer
|
||||
void RemoveKey(CIniKeyW* pKey);
|
||||
// Removes a single key by string
|
||||
void RemoveKey(std::wstring sKey);
|
||||
// Removes all the keys in the section
|
||||
void RemoveAllKeys();
|
||||
// Returns a CIniKeyW pointer to the key by name, NULL if it was not found
|
||||
CIniKeyW* GetKey(std::wstring sKeyName) const;
|
||||
// Returns all keys in the section by KeyIndex only to be used for enumeration
|
||||
const KeyIndexW& GetKeys() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::wstring GetKeyValue(std::wstring sKey) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue(std::wstring sKey, const std::wstring& sValue);
|
||||
// Sets the section name, returns true on success, fails if the section
|
||||
// name sSectionName already exists
|
||||
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;
|
||||
// Name of the section
|
||||
std::wstring m_sSectionName;
|
||||
// List of CIniKeyW pointers ( Keys in the section )
|
||||
KeyIndexW m_keys;
|
||||
}; // End of CIniSectionW
|
||||
// Typedef of a List of CIniSectionW pointers
|
||||
struct ci_less_w
|
||||
{
|
||||
bool operator()(const CIniSectionW* s1, const CIniSectionW* s2) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return wcscasecmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
return wcscasecmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
#else
|
||||
return _wcsicmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
return _wcsicmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<CIniSectionW*,ci_less_w> SecIndexW;
|
||||
typedef std::set<CIniSectionW*, ci_less_w> SecIndexW;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Added for VC6 Support
|
||||
// Added for VC6 Support
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1300)
|
||||
friend class CIniSectionW;
|
||||
friend class CIniSectionW;
|
||||
#endif
|
||||
#endif
|
||||
public:
|
||||
// Adds a section to the CIniFileW object, returns a CIniFileW pointer to the new or existing object
|
||||
CIniSectionW* AddSection( std::wstring sSection );
|
||||
// Removes section by pointer
|
||||
void RemoveSection( CIniSectionW* pSection );
|
||||
// Removes a section by its name sSection
|
||||
void RemoveSection( std::wstring sSection );
|
||||
// Removes all existing sections
|
||||
void RemoveAllSections( );
|
||||
// Returns a CIniSectionW* to the section by name, NULL if it was not found
|
||||
CIniSectionW* GetSection( std::wstring sSection ) const;
|
||||
// Returns all sections in the inifile by SecIndex, only to be used for enumeration (DO NOT KEEP THE REF OR TRY TO DELETE STUFF!)
|
||||
const SecIndexW& GetSections() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::wstring GetKeyValue( const std::wstring& sSection, const std::wstring& sKey ) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue( const std::wstring& sSection, const std::wstring& sKey, const std::wstring& sValue );
|
||||
// Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSectionName
|
||||
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);
|
||||
// Adds a section to the CIniFileW object, returns a CIniFileW pointer to the new or existing object
|
||||
CIniSectionW* AddSection(std::wstring sSection);
|
||||
// Removes section by pointer
|
||||
void RemoveSection(CIniSectionW* pSection);
|
||||
// Removes a section by its name sSection
|
||||
void RemoveSection(std::wstring sSection);
|
||||
// Removes all existing sections
|
||||
void RemoveAllSections();
|
||||
// Returns a CIniSectionW* to the section by name, NULL if it was not found
|
||||
CIniSectionW* GetSection(std::wstring sSection) const;
|
||||
// Returns all sections in the inifile by SecIndex, only to be used for enumeration (DO NOT KEEP THE REF OR TRY TO DELETE STUFF!)
|
||||
const SecIndexW& GetSections() const;
|
||||
// Returns a KeyValue at a certain section
|
||||
std::wstring GetKeyValue(const std::wstring& sSection, const std::wstring& sKey) const;
|
||||
// Sets a KeyValuePair at a certain section
|
||||
void SetKeyValue(const std::wstring& sSection, const std::wstring& sKey, const std::wstring& sValue);
|
||||
// Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSectionName
|
||||
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 );
|
||||
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
|
||||
// List of CIniSectionW pointers ( List of sections in the class )
|
||||
SecIndexW m_sections;
|
||||
CIniFileW(const CIniFileW&); // No Copy
|
||||
CIniFileW& operator=(const CIniFileW&); // No Copy
|
||||
// List of CIniSectionW pointers ( List of sections in the class )
|
||||
SecIndexW m_sections;
|
||||
}; // End of CIniFileW
|
||||
|
||||
// Basic typedefs for ease of use
|
||||
|
@ -542,4 +568,3 @@ std::wstring str_to_wstr(const std::string& arg);
|
|||
std::string wstr_to_str(const std::wstring& arg);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -21,237 +21,246 @@
|
|||
|
||||
extern HINSTANCE hInst;
|
||||
|
||||
namespace shared{ namespace rawinput{
|
||||
|
||||
static std::vector<ParseRawInputCB *> callbacks;
|
||||
|
||||
HWND msgWindow = nullptr;
|
||||
WNDPROC eatenWndProc = nullptr;
|
||||
HWND eatenWnd = nullptr;
|
||||
HHOOK hHook = nullptr, hHookWnd = nullptr, hHookKB = nullptr;
|
||||
bool skipInput = false;
|
||||
|
||||
void RegisterCallback(ParseRawInputCB *cb)
|
||||
namespace shared
|
||||
{
|
||||
if (cb && std::find(callbacks.begin(), callbacks.end(), cb) == callbacks.end())
|
||||
callbacks.push_back(cb);
|
||||
}
|
||||
|
||||
void UnregisterCallback(ParseRawInputCB *cb)
|
||||
{
|
||||
auto it = std::find(callbacks.begin(), callbacks.end(), cb);
|
||||
if (it != callbacks.end())
|
||||
callbacks.erase(it);
|
||||
}
|
||||
|
||||
static POINT origCursorPos;
|
||||
static POINT center;
|
||||
static bool cursorCaptured = false;
|
||||
|
||||
static void WindowResized(HWND hWnd)
|
||||
{
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
|
||||
static void CursorCapture(HWND hWnd)
|
||||
{
|
||||
OSDebugOut(TEXT("Capture cursor\n"));
|
||||
SetCapture(hWnd);
|
||||
ShowCursor(0);
|
||||
|
||||
GetCursorPos(&origCursorPos);
|
||||
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
cursorCaptured = true;
|
||||
}
|
||||
|
||||
static void CursorRelease()
|
||||
{
|
||||
OSDebugOut(TEXT("Release cursor\n"));
|
||||
if (cursorCaptured)
|
||||
namespace rawinput
|
||||
{
|
||||
ClipCursor(0);
|
||||
ReleaseCapture();
|
||||
ShowCursor(1);
|
||||
SetCursorPos(origCursorPos.x, origCursorPos.y);
|
||||
cursorCaptured = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void ToggleCursor(HWND hWnd, RAWKEYBOARD &k)
|
||||
{
|
||||
static bool shiftDown = false;
|
||||
static std::vector<ParseRawInputCB*> callbacks;
|
||||
|
||||
if (k.VKey == VK_SHIFT || k.VKey == VK_LSHIFT || k.VKey == VK_RSHIFT)
|
||||
shiftDown = !(k.Flags & RI_KEY_BREAK);
|
||||
HWND msgWindow = nullptr;
|
||||
WNDPROC eatenWndProc = nullptr;
|
||||
HWND eatenWnd = nullptr;
|
||||
HHOOK hHook = nullptr, hHookWnd = nullptr, hHookKB = nullptr;
|
||||
bool skipInput = false;
|
||||
|
||||
if (shiftDown && k.VKey == VK_F11 && !k.Flags)
|
||||
{
|
||||
if (!cursorCaptured)
|
||||
CursorCapture(hWnd);
|
||||
else
|
||||
CursorRelease();
|
||||
}
|
||||
}
|
||||
|
||||
static int RegisterRaw(HWND hWnd)
|
||||
{
|
||||
msgWindow = hWnd;
|
||||
RAWINPUTDEVICE Rid[4];
|
||||
Rid[0].usUsagePage = 0x01;
|
||||
Rid[0].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
Rid[0].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE; // adds game pad
|
||||
Rid[0].hwndTarget = hWnd;
|
||||
|
||||
Rid[1].usUsagePage = 0x01;
|
||||
Rid[1].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
Rid[1].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE; // adds joystick
|
||||
Rid[1].hwndTarget = hWnd;
|
||||
|
||||
Rid[2].usUsagePage = 0x01;
|
||||
Rid[2].usUsage = HID_USAGE_GENERIC_KEYBOARD;
|
||||
Rid[2].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE;// | RIDEV_NOLEGACY; // adds HID keyboard //and also !ignores legacy keyboard messages
|
||||
Rid[2].hwndTarget = hWnd;
|
||||
|
||||
Rid[3].usUsagePage = 0x01;
|
||||
Rid[3].usUsage = HID_USAGE_GENERIC_MOUSE;
|
||||
Rid[3].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE;
|
||||
Rid[3].hwndTarget = hWnd;
|
||||
|
||||
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;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg) {
|
||||
case WM_ACTIVATE:
|
||||
OSDebugOut(TEXT("****** WM_ACTIVATE ****** %p %d\n"), hWnd, LOWORD(wParam) != WA_INACTIVE);
|
||||
skipInput = LOWORD(wParam) == WA_INACTIVE;
|
||||
break;
|
||||
case WM_SETFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_SETFOCUS ****** %p\n"), hWnd);
|
||||
skipInput = false;
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_KILLFOCUS ****** %p\n"), hWnd);
|
||||
skipInput = true;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK RawInputProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PRAWINPUT pRawInput;
|
||||
UINT bufferSize=0;
|
||||
|
||||
switch(uMsg) {
|
||||
case WM_CREATE:
|
||||
if (eatenWnd == nullptr)
|
||||
RegisterRaw(hWnd);
|
||||
break;
|
||||
case WM_INPUT: {
|
||||
if (skipInput) break;
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
|
||||
pRawInput = (PRAWINPUT)malloc(bufferSize);
|
||||
|
||||
if (!pRawInput)
|
||||
break;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, pRawInput, &bufferSize, sizeof(RAWINPUTHEADER)) > 0) {
|
||||
|
||||
if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
|
||||
ToggleCursor(hWnd, pRawInput->data.keyboard);
|
||||
|
||||
for (auto cb : callbacks)
|
||||
cb->ParseRawInput(pRawInput);
|
||||
void RegisterCallback(ParseRawInputCB* cb)
|
||||
{
|
||||
if (cb && std::find(callbacks.begin(), callbacks.end(), cb) == callbacks.end())
|
||||
callbacks.push_back(cb);
|
||||
}
|
||||
|
||||
free(pRawInput);
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
OSDebugOut(TEXT("****** WM_ACTIVATE ****** %p %d\n"), hWnd, LOWORD(wParam) != WA_INACTIVE);
|
||||
skipInput = LOWORD(wParam) == WA_INACTIVE;
|
||||
if (LOWORD(wParam) == WA_INACTIVE)
|
||||
CursorRelease();
|
||||
break;
|
||||
case WM_SETFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_SETFOCUS ****** %p\n"), hWnd);
|
||||
//skipInput = false; //TODO when the hell is WM_SETFOCUS sent? seems like only when mouse is capped
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_KILLFOCUS ****** %p\n"), hWnd);
|
||||
//skipInput = true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (cursorCaptured)
|
||||
WindowResized(hWnd);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
if (eatenWnd == nullptr)
|
||||
RegisterRaw(nullptr);
|
||||
Uninitialize();
|
||||
break;
|
||||
}
|
||||
void UnregisterCallback(ParseRawInputCB* cb)
|
||||
{
|
||||
auto it = std::find(callbacks.begin(), callbacks.end(), cb);
|
||||
if (it != callbacks.end())
|
||||
callbacks.erase(it);
|
||||
}
|
||||
|
||||
if(eatenWndProc)
|
||||
return CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
//else
|
||||
// return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
static POINT origCursorPos;
|
||||
static POINT center;
|
||||
static bool cursorCaptured = false;
|
||||
|
||||
static LRESULT CALLBACK HookProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MSG *msg = reinterpret_cast<MSG*> (lParam);
|
||||
static void WindowResized(HWND hWnd)
|
||||
{
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
|
||||
//fprintf(stderr, "hook: %d, %d, %d\n", code, wParam, lParam);
|
||||
if(code == HC_ACTION)
|
||||
RawInputProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(hHook, code, wParam, lParam);
|
||||
}
|
||||
static void CursorCapture(HWND hWnd)
|
||||
{
|
||||
OSDebugOut(TEXT("Capture cursor\n"));
|
||||
SetCapture(hWnd);
|
||||
ShowCursor(0);
|
||||
|
||||
static LRESULT CALLBACK HookWndProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MSG *msg = reinterpret_cast<MSG*> (lParam);
|
||||
GetCursorPos(&origCursorPos);
|
||||
|
||||
//fprintf(stderr, "hook: %d, %d, %d\n", code, wParam, lParam);
|
||||
if (code == HC_ACTION)
|
||||
MyWndProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(hHookWnd, code, wParam, lParam);
|
||||
}
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
cursorCaptured = true;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK KBHookProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
fprintf(stderr, "kb hook: %d, %zd, %zd\n", code, wParam, lParam);
|
||||
KBDLLHOOKSTRUCT *kb = reinterpret_cast<KBDLLHOOKSTRUCT*> (lParam);
|
||||
//if(code == HC_ACTION)
|
||||
// RawInputProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(0, code, wParam, lParam);
|
||||
}
|
||||
static void CursorRelease()
|
||||
{
|
||||
OSDebugOut(TEXT("Release cursor\n"));
|
||||
if (cursorCaptured)
|
||||
{
|
||||
ClipCursor(0);
|
||||
ReleaseCapture();
|
||||
ShowCursor(1);
|
||||
SetCursorPos(origCursorPos.x, origCursorPos.y);
|
||||
cursorCaptured = false;
|
||||
}
|
||||
}
|
||||
|
||||
int Initialize(void *ptr)
|
||||
{
|
||||
HWND hWnd = reinterpret_cast<HWND> (ptr);
|
||||
if (!InitHid())
|
||||
return 0;
|
||||
static void ToggleCursor(HWND hWnd, RAWKEYBOARD& k)
|
||||
{
|
||||
static bool shiftDown = false;
|
||||
|
||||
if (k.VKey == VK_SHIFT || k.VKey == VK_LSHIFT || k.VKey == VK_RSHIFT)
|
||||
shiftDown = !(k.Flags & RI_KEY_BREAK);
|
||||
|
||||
if (shiftDown && k.VKey == VK_F11 && !k.Flags)
|
||||
{
|
||||
if (!cursorCaptured)
|
||||
CursorCapture(hWnd);
|
||||
else
|
||||
CursorRelease();
|
||||
}
|
||||
}
|
||||
|
||||
static int RegisterRaw(HWND hWnd)
|
||||
{
|
||||
msgWindow = hWnd;
|
||||
RAWINPUTDEVICE Rid[4];
|
||||
Rid[0].usUsagePage = 0x01;
|
||||
Rid[0].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
Rid[0].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE; // adds game pad
|
||||
Rid[0].hwndTarget = hWnd;
|
||||
|
||||
Rid[1].usUsagePage = 0x01;
|
||||
Rid[1].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
Rid[1].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE; // adds joystick
|
||||
Rid[1].hwndTarget = hWnd;
|
||||
|
||||
Rid[2].usUsagePage = 0x01;
|
||||
Rid[2].usUsage = HID_USAGE_GENERIC_KEYBOARD;
|
||||
Rid[2].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE; // | RIDEV_NOLEGACY; // adds HID keyboard //and also !ignores legacy keyboard messages
|
||||
Rid[2].hwndTarget = hWnd;
|
||||
|
||||
Rid[3].usUsagePage = 0x01;
|
||||
Rid[3].usUsage = HID_USAGE_GENERIC_MOUSE;
|
||||
Rid[3].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE;
|
||||
Rid[3].hwndTarget = hWnd;
|
||||
|
||||
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;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
OSDebugOut(TEXT("****** WM_ACTIVATE ****** %p %d\n"), hWnd, LOWORD(wParam) != WA_INACTIVE);
|
||||
skipInput = LOWORD(wParam) == WA_INACTIVE;
|
||||
break;
|
||||
case WM_SETFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_SETFOCUS ****** %p\n"), hWnd);
|
||||
skipInput = false;
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_KILLFOCUS ****** %p\n"), hWnd);
|
||||
skipInput = true;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK RawInputProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PRAWINPUT pRawInput;
|
||||
UINT bufferSize = 0;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
if (eatenWnd == nullptr)
|
||||
RegisterRaw(hWnd);
|
||||
break;
|
||||
case WM_INPUT:
|
||||
{
|
||||
if (skipInput)
|
||||
break;
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
|
||||
pRawInput = (PRAWINPUT)malloc(bufferSize);
|
||||
|
||||
if (!pRawInput)
|
||||
break;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, pRawInput, &bufferSize, sizeof(RAWINPUTHEADER)) > 0)
|
||||
{
|
||||
|
||||
if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
|
||||
ToggleCursor(hWnd, pRawInput->data.keyboard);
|
||||
|
||||
for (auto cb : callbacks)
|
||||
cb->ParseRawInput(pRawInput);
|
||||
}
|
||||
|
||||
free(pRawInput);
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
OSDebugOut(TEXT("****** WM_ACTIVATE ****** %p %d\n"), hWnd, LOWORD(wParam) != WA_INACTIVE);
|
||||
skipInput = LOWORD(wParam) == WA_INACTIVE;
|
||||
if (LOWORD(wParam) == WA_INACTIVE)
|
||||
CursorRelease();
|
||||
break;
|
||||
case WM_SETFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_SETFOCUS ****** %p\n"), hWnd);
|
||||
//skipInput = false; //TODO when the hell is WM_SETFOCUS sent? seems like only when mouse is capped
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
OSDebugOut(TEXT("****** WM_KILLFOCUS ****** %p\n"), hWnd);
|
||||
//skipInput = true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (cursorCaptured)
|
||||
WindowResized(hWnd);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
if (eatenWnd == nullptr)
|
||||
RegisterRaw(nullptr);
|
||||
Uninitialize();
|
||||
break;
|
||||
}
|
||||
|
||||
if (eatenWndProc)
|
||||
return CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
//else
|
||||
// return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK HookProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MSG* msg = reinterpret_cast<MSG*>(lParam);
|
||||
|
||||
//fprintf(stderr, "hook: %d, %d, %d\n", code, wParam, lParam);
|
||||
if (code == HC_ACTION)
|
||||
RawInputProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(hHook, code, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK HookWndProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MSG* msg = reinterpret_cast<MSG*>(lParam);
|
||||
|
||||
//fprintf(stderr, "hook: %d, %d, %d\n", code, wParam, lParam);
|
||||
if (code == HC_ACTION)
|
||||
MyWndProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(hHookWnd, code, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK KBHookProc(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
fprintf(stderr, "kb hook: %d, %zd, %zd\n", code, wParam, lParam);
|
||||
KBDLLHOOKSTRUCT* kb = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
//if(code == HC_ACTION)
|
||||
// RawInputProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
|
||||
return CallNextHookEx(0, code, wParam, lParam);
|
||||
}
|
||||
|
||||
int Initialize(void* ptr)
|
||||
{
|
||||
HWND hWnd = reinterpret_cast<HWND>(ptr);
|
||||
if (!InitHid())
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
if (!RegisterRaw(hWnd))
|
||||
|
@ -261,27 +270,28 @@ int Initialize(void *ptr)
|
|||
//hHookKB = SetWindowsHookEx(WH_KEYBOARD_LL, KBHookProc, hInst, 0);
|
||||
//int err = GetLastError();
|
||||
#else
|
||||
eatenWnd = hWnd;
|
||||
eatenWndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)RawInputProc);
|
||||
RegisterRaw(hWnd);
|
||||
eatenWnd = hWnd;
|
||||
eatenWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)RawInputProc);
|
||||
RegisterRaw(hWnd);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Uninitialize()
|
||||
{
|
||||
if(hHook)
|
||||
{
|
||||
UnhookWindowsHookEx(hHook);
|
||||
//UnhookWindowsHookEx(hHookKB);
|
||||
hHook = 0;
|
||||
}
|
||||
if(eatenWnd)
|
||||
RegisterRaw(nullptr);
|
||||
if(eatenWnd && eatenWndProc)
|
||||
SetWindowLongPtr(eatenWnd, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
|
||||
eatenWndProc = nullptr;
|
||||
eatenWnd = nullptr;
|
||||
}
|
||||
void Uninitialize()
|
||||
{
|
||||
if (hHook)
|
||||
{
|
||||
UnhookWindowsHookEx(hHook);
|
||||
//UnhookWindowsHookEx(hHookKB);
|
||||
hHook = 0;
|
||||
}
|
||||
if (eatenWnd)
|
||||
RegisterRaw(nullptr);
|
||||
if (eatenWnd && eatenWndProc)
|
||||
SetWindowLongPtr(eatenWnd, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
|
||||
eatenWndProc = nullptr;
|
||||
eatenWnd = nullptr;
|
||||
}
|
||||
|
||||
}} //namespace
|
||||
} // namespace rawinput
|
||||
} // namespace shared
|
||||
|
|
|
@ -18,17 +18,21 @@
|
|||
#include <setupapi.h>
|
||||
#include "hidapi.h"
|
||||
|
||||
namespace shared{ namespace rawinput{
|
||||
|
||||
class ParseRawInputCB
|
||||
namespace shared
|
||||
{
|
||||
namespace rawinput
|
||||
{
|
||||
|
||||
class ParseRawInputCB
|
||||
{
|
||||
public:
|
||||
virtual void ParseRawInput(PRAWINPUT pRawInput) = 0;
|
||||
};
|
||||
virtual void ParseRawInput(PRAWINPUT pRawInput) = 0;
|
||||
};
|
||||
|
||||
int Initialize(void *hWnd);
|
||||
void Uninitialize();
|
||||
int Initialize(void* hWnd);
|
||||
void Uninitialize();
|
||||
|
||||
void RegisterCallback(ParseRawInputCB *cb);
|
||||
void UnregisterCallback(ParseRawInputCB *cb);
|
||||
}}
|
||||
void RegisterCallback(ParseRawInputCB* cb);
|
||||
void UnregisterCallback(ParseRawInputCB* cb);
|
||||
} // namespace rawinput
|
||||
} // namespace shared
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
#if 0
|
||||
#define DPRINTF OSDebugOut
|
||||
#else
|
||||
#define DPRINTF(...) do{}while(0)
|
||||
#define DPRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
RingBuffer::RingBuffer()
|
||||
|
@ -33,19 +36,20 @@ RingBuffer::RingBuffer()
|
|||
{
|
||||
}
|
||||
|
||||
RingBuffer::RingBuffer(size_t capacity) : RingBuffer()
|
||||
RingBuffer::RingBuffer(size_t capacity)
|
||||
: RingBuffer()
|
||||
{
|
||||
reserve(capacity);
|
||||
}
|
||||
|
||||
RingBuffer::~RingBuffer()
|
||||
{
|
||||
delete [] m_data;
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
void RingBuffer::reserve(size_t capacity)
|
||||
{
|
||||
delete [] m_data;
|
||||
delete[] m_data;
|
||||
m_data = new char[capacity];
|
||||
memset(m_data, 0, capacity);
|
||||
m_capacity = capacity;
|
||||
|
@ -63,7 +67,7 @@ size_t RingBuffer::size() const
|
|||
size = 0;
|
||||
}
|
||||
else if (m_begin < m_end)
|
||||
size = m_end - m_begin; // [ b...e ]
|
||||
size = m_end - m_begin; // [ b...e ]
|
||||
else
|
||||
size = m_capacity - m_begin + m_end; // [...e b...]
|
||||
|
||||
|
@ -71,7 +75,7 @@ size_t RingBuffer::size() const
|
|||
return size;
|
||||
}
|
||||
|
||||
size_t RingBuffer::read(uint8_t *dst, size_t nbytes)
|
||||
size_t RingBuffer::read(uint8_t* dst, size_t nbytes)
|
||||
{
|
||||
size_t to_read = nbytes;
|
||||
while (to_read > 0 && size() > 0)
|
||||
|
@ -85,12 +89,12 @@ size_t RingBuffer::read(uint8_t *dst, size_t nbytes)
|
|||
return nbytes - to_read;
|
||||
}
|
||||
|
||||
void RingBuffer::write(uint8_t *src, size_t nbytes)
|
||||
void RingBuffer::write(uint8_t* src, size_t nbytes)
|
||||
{
|
||||
size_t bytes;
|
||||
while (nbytes > 0)
|
||||
{
|
||||
bytes = std::min(nbytes, m_capacity - m_end);
|
||||
bytes = std::min(nbytes, m_capacity - m_end);
|
||||
memcpy(back(), src, bytes);
|
||||
write(bytes);
|
||||
src += bytes;
|
||||
|
@ -105,12 +109,12 @@ size_t RingBuffer::peek_write(bool overwrite) const
|
|||
if (overwrite)
|
||||
return m_capacity - m_end;
|
||||
|
||||
if (m_end < m_begin) // [...e b...]
|
||||
if (m_end < m_begin) // [...e b...]
|
||||
peek = m_begin - m_end;
|
||||
else if (m_end < m_capacity) // [ b...e ]
|
||||
peek = m_capacity - m_end;
|
||||
else
|
||||
peek = m_begin; // [ b.......e]
|
||||
peek = m_begin; // [ b.......e]
|
||||
|
||||
DPRINTF(TEXT("peek_write %zu\n"), peek);
|
||||
return peek;
|
||||
|
@ -126,12 +130,12 @@ size_t RingBuffer::peek_read() const
|
|||
else
|
||||
peek = 0;
|
||||
}
|
||||
else if (m_begin < m_end) // [ b...e ]
|
||||
else if (m_begin < m_end) // [ b...e ]
|
||||
peek = m_end - m_begin;
|
||||
else if (m_begin < m_capacity) // [...e b...]
|
||||
else if (m_begin < m_capacity) // [...e b...]
|
||||
peek = m_capacity - m_begin;
|
||||
else
|
||||
peek = m_end; // [...e b]
|
||||
peek = m_end; // [...e b]
|
||||
|
||||
DPRINTF(TEXT("peek_read %zu\n"), peek);
|
||||
return peek;
|
||||
|
@ -171,11 +175,11 @@ void RingBuffer::write(size_t bytes)
|
|||
|
||||
// push m_begin forward if m_end overlaps it
|
||||
if ((m_end < m_begin && m_end + bytes > m_begin) ||
|
||||
m_end + bytes > m_begin + m_capacity)
|
||||
m_end + bytes > m_begin + m_capacity)
|
||||
{
|
||||
m_overrun = true;
|
||||
m_begin = (m_end + bytes) % m_capacity;
|
||||
m_end = m_begin;
|
||||
m_end = m_begin;
|
||||
}
|
||||
else
|
||||
m_end = (m_end + bytes) % m_capacity;
|
||||
|
@ -186,7 +190,7 @@ void RingBuffer::write(size_t bytes)
|
|||
|
||||
void RingBuffer::read(size_t bytes)
|
||||
{
|
||||
assert( bytes <= size() );
|
||||
assert(bytes <= size());
|
||||
|
||||
m_overrun = false;
|
||||
if ((m_begin < m_end && m_begin + bytes > m_end) ||
|
||||
|
|
|
@ -28,6 +28,7 @@ using sec = std::chrono::seconds;
|
|||
class RingBuffer
|
||||
{
|
||||
RingBuffer(RingBuffer&) = delete;
|
||||
|
||||
public:
|
||||
RingBuffer();
|
||||
RingBuffer(size_t capacity);
|
||||
|
@ -37,18 +38,24 @@ public:
|
|||
//size_t read(char *data, size_t bytes);
|
||||
|
||||
// Overwrites old data if nbytes > size()
|
||||
void write(uint8_t *src, size_t nbytes);
|
||||
size_t read(uint8_t *dst, size_t nbytes);
|
||||
void write(uint8_t* src, size_t nbytes);
|
||||
size_t read(uint8_t* dst, size_t nbytes);
|
||||
|
||||
// just move pointers around
|
||||
void write(size_t bytes);
|
||||
void read(size_t bytes);
|
||||
|
||||
template<typename T>
|
||||
void write(size_t samples) { write(samples * sizeof(T)); }
|
||||
template <typename T>
|
||||
void write(size_t samples)
|
||||
{
|
||||
write(samples * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void read(size_t samples) { read (samples * sizeof(T)); }
|
||||
template <typename 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
|
||||
|
@ -56,13 +63,13 @@ public:
|
|||
size_t peek_write(bool overwrite = false) const;
|
||||
size_t peek_read() const;
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
size_t peek_write(bool overwrite = false) const
|
||||
{
|
||||
return peek_write(overwrite) / sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
size_t peek_read() const
|
||||
{
|
||||
return peek_read() / sizeof(T);
|
||||
|
@ -70,33 +77,39 @@ public:
|
|||
|
||||
// amount of valid data, may need to read twice
|
||||
size_t size() const;
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
size_t size() const
|
||||
{
|
||||
return size() / sizeof(T);
|
||||
}
|
||||
size_t capacity() const { return m_capacity; }
|
||||
char* front(){ return m_data + m_begin; }
|
||||
char* back(){ return m_data + m_end; }
|
||||
char* front() { return m_data + m_begin; }
|
||||
char* back() { return m_data + m_end; }
|
||||
|
||||
template<typename T>
|
||||
T* front() { return (T*)(m_data + m_begin); }
|
||||
template <typename T>
|
||||
T* front()
|
||||
{
|
||||
return (T*)(m_data + m_begin);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* back() { return (T*)(m_data + m_end); }
|
||||
template <typename T>
|
||||
T* back()
|
||||
{
|
||||
return (T*)(m_data + m_end);
|
||||
}
|
||||
|
||||
long long MilliSecsSinceLastWrite()
|
||||
{
|
||||
return std::chrono::duration_cast<ms>(hrc::now()-mLastWrite).count();
|
||||
return std::chrono::duration_cast<ms>(hrc::now() - mLastWrite).count();
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_capacity;
|
||||
char *m_data;
|
||||
size_t m_capacity;
|
||||
char* m_data;
|
||||
size_t m_begin;
|
||||
bool m_overrun;
|
||||
size_t m_end;
|
||||
size_t m_end;
|
||||
hrc::time_point mLastWrite = hrc::time_point(ns(0));
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,22 +20,23 @@
|
|||
#include "rawinput.h"
|
||||
#endif
|
||||
|
||||
namespace shared {
|
||||
namespace shared
|
||||
{
|
||||
|
||||
void Initialize(void *ptr)
|
||||
void Initialize(void* ptr)
|
||||
{
|
||||
// Keeping it simple, for now
|
||||
#if defined(BUILD_RAW)
|
||||
if (!shared::rawinput::Initialize(ptr))
|
||||
throw std::runtime_error("Failed to initialize raw input!");
|
||||
#endif
|
||||
// Keeping it simple, for now
|
||||
#if defined(BUILD_RAW)
|
||||
if (!shared::rawinput::Initialize(ptr))
|
||||
throw std::runtime_error("Failed to initialize raw input!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Uninitialize(/*void *ptr*/)
|
||||
{
|
||||
#if defined(BUILD_RAW)
|
||||
shared::rawinput::Uninitialize(/*ptr*/);
|
||||
#endif
|
||||
#if defined(BUILD_RAW)
|
||||
shared::rawinput::Uninitialize(/*ptr*/);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace shared
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
namespace shared {
|
||||
void Initialize(void *ptr);
|
||||
namespace shared
|
||||
{
|
||||
void Initialize(void* ptr);
|
||||
void Uninitialize(/*void *ptr*/);
|
||||
};
|
||||
}; // namespace shared
|
||||
|
|
|
@ -35,450 +35,524 @@
|
|||
#include "jpgd/jpgd.h"
|
||||
#include "jo_mpeg.h"
|
||||
|
||||
GtkWidget *new_combobox(const char* label, GtkWidget *vbox); // src/linux/config-gtk.cpp
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
|
||||
|
||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
namespace linux_api
|
||||
{
|
||||
namespace linux_api
|
||||
{
|
||||
|
||||
static pthread_t _eyetoy_thread;
|
||||
static pthread_t *eyetoy_thread = &_eyetoy_thread;
|
||||
static unsigned char eyetoy_running = 0;
|
||||
static pthread_t _eyetoy_thread;
|
||||
static pthread_t* eyetoy_thread = &_eyetoy_thread;
|
||||
static unsigned char eyetoy_running = 0;
|
||||
|
||||
static int fd = -1;
|
||||
buffer_t *buffers;
|
||||
static unsigned int n_buffers;
|
||||
static int out_buf;
|
||||
static unsigned int pixelformat;
|
||||
static int fd = -1;
|
||||
buffer_t* buffers;
|
||||
static unsigned int n_buffers;
|
||||
static int out_buf;
|
||||
static unsigned int pixelformat;
|
||||
|
||||
buffer_t mpeg_buffer;
|
||||
std::mutex mpeg_mutex;
|
||||
buffer_t mpeg_buffer;
|
||||
std::mutex mpeg_mutex;
|
||||
|
||||
static int xioctl(int fh, unsigned long int request, void *arg) {
|
||||
int r;
|
||||
do {
|
||||
r = ioctl(fh, request, arg);
|
||||
} while (-1 == r && EINTR == errno);
|
||||
return r;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, 320, 240, JO_RGB24, JO_FLIP_X, JO_NONE);
|
||||
free(rgbData);
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
} else {
|
||||
fprintf(stderr, "unk format %c%c%c%c\n", pixelformat, pixelformat>>8, pixelformat>>16, pixelformat>>24);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
case EIO:
|
||||
default:
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_DQBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(buf.index < n_buffers);
|
||||
|
||||
process_image((const unsigned char*) buffers[buf.index].start, buf.bytesused);
|
||||
|
||||
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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++) {
|
||||
snprintf(dev_name, sizeof(dev_name), "/dev/video%d", index);
|
||||
|
||||
if ((fd = open(dev_name, O_RDONLY)) < 0) {
|
||||
continue;
|
||||
static int xioctl(int fh, unsigned long int request, void* arg)
|
||||
{
|
||||
int r;
|
||||
do
|
||||
{
|
||||
r = ioctl(fh, request, arg);
|
||||
} while (-1 == r && EINTR == errno);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0) {
|
||||
devList.push_back((char*)cap.card);
|
||||
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();
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
return devList;
|
||||
}
|
||||
|
||||
static int v4l_open(std::string selectedDevice) {
|
||||
char dev_name[64];
|
||||
struct v4l2_capability cap;
|
||||
|
||||
fd = -1;
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CLEAR(cap);
|
||||
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) {
|
||||
goto cont;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, 320, 240, JO_RGB24, JO_FLIP_X, JO_NONE);
|
||||
free(rgbData);
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "unk format %c%c%c%c\n", pixelformat, pixelformat >> 8, pixelformat >> 16, pixelformat >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
static int read_frame()
|
||||
{
|
||||
struct v4l2_buffer buf;
|
||||
CLEAR(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (fd < 0) {
|
||||
snprintf(dev_name, sizeof(dev_name), "/dev/video0");
|
||||
fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
|
||||
if (-1 == fd) {
|
||||
fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
cont:
|
||||
|
||||
CLEAR(cap);
|
||||
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
|
||||
if (EINVAL == errno) {
|
||||
fprintf(stderr, "%s is no V4L2 device\n", dev_name);
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYCAP", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
fprintf(stderr, "%s does not support streaming i/o\n", dev_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct v4l2_cropcap cropcap;
|
||||
CLEAR(cropcap);
|
||||
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
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) {
|
||||
case EINVAL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case EIO:
|
||||
default:
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_DQBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct v4l2_format fmt;
|
||||
CLEAR(fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.fmt.pix.width = 320;
|
||||
fmt.fmt.pix.height = 240;
|
||||
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
assert(buf.index < n_buffers);
|
||||
|
||||
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
|
||||
);
|
||||
process_image((const unsigned char*)buffers[buf.index].start, buf.bytesused);
|
||||
|
||||
struct v4l2_requestbuffers req;
|
||||
CLEAR(req);
|
||||
req.count = 4;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
|
||||
if (EINVAL == errno) {
|
||||
fprintf(stderr, "%s does not support memory mapping\n", dev_name);
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_REQBUFS", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
CLEAR(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = n_buffers;
|
||||
|
||||
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
buffers[n_buffers].length = buf.length;
|
||||
buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
|
||||
std::vector<std::string> getDevList()
|
||||
{
|
||||
std::vector<std::string> devList;
|
||||
char dev_name[64];
|
||||
int fd;
|
||||
struct v4l2_capability cap;
|
||||
|
||||
if (MAP_FAILED == buffers[n_buffers].start) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "mmap", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < 64; index++)
|
||||
{
|
||||
snprintf(dev_name, sizeof(dev_name), "/dev/video%d", index);
|
||||
|
||||
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)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
enum v4l2_buf_type type;
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_STREAMON", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void* v4l_thread(void *arg) {
|
||||
while(eyetoy_running) {
|
||||
for (;;) {
|
||||
fd_set fds;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
struct timeval timeout = {2, 0}; // 2sec
|
||||
int ret = select(fd + 1, &fds, NULL, NULL, &timeout);
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
if ((fd = open(dev_name, O_RDONLY)) < 0)
|
||||
{
|
||||
continue;
|
||||
fprintf(stderr, "%s error %d, %s\n", "select", errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0)
|
||||
{
|
||||
devList.push_back((char*)cap.card);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
return devList;
|
||||
}
|
||||
|
||||
static int v4l_open(std::string selectedDevice)
|
||||
{
|
||||
char dev_name[64];
|
||||
struct v4l2_capability cap;
|
||||
|
||||
fd = -1;
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CLEAR(cap);
|
||||
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)
|
||||
{
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "select timeout\n");
|
||||
break;
|
||||
if (fd < 0)
|
||||
{
|
||||
snprintf(dev_name, sizeof(dev_name), "/dev/video0");
|
||||
fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
|
||||
if (-1 == fd)
|
||||
{
|
||||
fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_frame())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
cont:
|
||||
|
||||
static int v4l_close() {
|
||||
enum v4l2_buf_type type;
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
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)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "munmap", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free(buffers);
|
||||
|
||||
if (-1 == close(fd)) {
|
||||
fprintf(stderr, "%s error %d, %s\n", "close", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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++) {
|
||||
unsigned char *ptr = rgbData + (y*width+x) * bytesPerPixel;
|
||||
ptr[0] = 255-y;
|
||||
ptr[1] = y;
|
||||
ptr[2] = 255-y;
|
||||
}
|
||||
}
|
||||
unsigned char *mpegData = (unsigned char*) calloc(1, width * height * bytesPerPixel);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, width, height, JO_RGB24, JO_NONE, JO_NONE);
|
||||
free(rgbData);
|
||||
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
}
|
||||
|
||||
int V4L2::Open() {
|
||||
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
|
||||
create_dummy_frame();
|
||||
if (eyetoy_running) {
|
||||
eyetoy_running = 0;
|
||||
pthread_join(*eyetoy_thread, NULL);
|
||||
v4l_close();
|
||||
}
|
||||
eyetoy_running = 1;
|
||||
std::string selectedDevice;
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), mPort, APINAME, N_DEVICE, selectedDevice);
|
||||
if (v4l_open(selectedDevice) != 0)
|
||||
return -1;
|
||||
pthread_create(eyetoy_thread, NULL, &v4l_thread, NULL);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int V4L2::Close() {
|
||||
if (eyetoy_running) {
|
||||
eyetoy_running = 0;
|
||||
pthread_join(*eyetoy_thread, NULL);
|
||||
v4l_close();
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int V4L2::GetImage(uint8_t *buf, int len) {
|
||||
mpeg_mutex.lock();
|
||||
int len2 = mpeg_buffer.length;
|
||||
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) {
|
||||
*(int*) data = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
}
|
||||
|
||||
int GtkConfigure(int port, const char* dev_type, void *data) {
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label;
|
||||
|
||||
std::string selectedDevice;
|
||||
LoadSetting(dev_type, port, APINAME, N_DEVICE, selectedDevice);
|
||||
|
||||
GtkWidget *dlg = gtk_dialog_new_with_buttons(
|
||||
"V4L2 Settings", GTK_WINDOW(data), GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dlg), 320, 75);
|
||||
|
||||
GtkWidget *dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
|
||||
GtkWidget *main_hbox = gtk_hbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg_area_box), main_hbox);
|
||||
GtkWidget *right_vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 5);
|
||||
|
||||
GtkWidget *rs_cb = new_combobox("Device:", right_vbox);
|
||||
|
||||
std::vector<std::string> devList = getDevList();
|
||||
int sel_idx = 0;
|
||||
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)) {
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), idx);
|
||||
sel_idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
int sel_new;
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(deviceChanged), (gpointer)&sel_new);
|
||||
|
||||
gtk_widget_show_all(dlg);
|
||||
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))) {
|
||||
ret = RESULT_FAILED;
|
||||
CLEAR(cap);
|
||||
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap))
|
||||
{
|
||||
if (EINVAL == errno)
|
||||
{
|
||||
fprintf(stderr, "%s is no V4L2 device\n", dev_name);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYCAP", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "%s does not support streaming i/o\n", dev_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct v4l2_cropcap cropcap;
|
||||
CLEAR(cropcap);
|
||||
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
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)
|
||||
{
|
||||
case EINVAL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct v4l2_format fmt;
|
||||
CLEAR(fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.fmt.pix.width = 320;
|
||||
fmt.fmt.pix.height = 240;
|
||||
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
|
||||
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);
|
||||
|
||||
struct v4l2_requestbuffers req;
|
||||
CLEAR(req);
|
||||
req.count = 4;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
|
||||
{
|
||||
if (EINVAL == errno)
|
||||
{
|
||||
fprintf(stderr, "%s does not support memory mapping\n", dev_name);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_REQBUFS", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
|
||||
{
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
CLEAR(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = n_buffers;
|
||||
|
||||
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "mmap", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
enum v4l2_buf_type type;
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_STREAMON", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ret = RESULT_CANCELED;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dlg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int V4L2::Configure(int port, const char *dev_type, void *data) {
|
||||
return GtkConfigure(port, dev_type, data);
|
||||
};
|
||||
static void* v4l_thread(void* arg)
|
||||
{
|
||||
while (eyetoy_running)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
fd_set fds;
|
||||
|
||||
} // namespace linux_api
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
struct timeval timeout = {2, 0}; // 2sec
|
||||
int ret = select(fd + 1, &fds, NULL, NULL, &timeout);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fprintf(stderr, "%s error %d, %s\n", "select", errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
fprintf(stderr, "select timeout\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (read_frame())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int v4l_close()
|
||||
{
|
||||
enum v4l2_buf_type type;
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "munmap", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free(buffers);
|
||||
|
||||
if (-1 == close(fd))
|
||||
{
|
||||
fprintf(stderr, "%s error %d, %s\n", "close", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
unsigned char* ptr = rgbData + (y * width + x) * bytesPerPixel;
|
||||
ptr[0] = 255 - y;
|
||||
ptr[1] = y;
|
||||
ptr[2] = 255 - y;
|
||||
}
|
||||
}
|
||||
unsigned char* mpegData = (unsigned char*)calloc(1, width * height * bytesPerPixel);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, width, height, JO_RGB24, JO_NONE, JO_NONE);
|
||||
free(rgbData);
|
||||
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
}
|
||||
|
||||
int V4L2::Open()
|
||||
{
|
||||
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
|
||||
create_dummy_frame();
|
||||
if (eyetoy_running)
|
||||
{
|
||||
eyetoy_running = 0;
|
||||
pthread_join(*eyetoy_thread, NULL);
|
||||
v4l_close();
|
||||
}
|
||||
eyetoy_running = 1;
|
||||
std::string selectedDevice;
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), mPort, APINAME, N_DEVICE, selectedDevice);
|
||||
if (v4l_open(selectedDevice) != 0)
|
||||
return -1;
|
||||
pthread_create(eyetoy_thread, NULL, &v4l_thread, NULL);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int V4L2::Close()
|
||||
{
|
||||
if (eyetoy_running)
|
||||
{
|
||||
eyetoy_running = 0;
|
||||
pthread_join(*eyetoy_thread, NULL);
|
||||
v4l_close();
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int V4L2::GetImage(uint8_t* buf, int len)
|
||||
{
|
||||
mpeg_mutex.lock();
|
||||
int len2 = mpeg_buffer.length;
|
||||
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)
|
||||
{
|
||||
*(int*)data = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
}
|
||||
|
||||
int GtkConfigure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label;
|
||||
|
||||
std::string selectedDevice;
|
||||
LoadSetting(dev_type, port, APINAME, N_DEVICE, selectedDevice);
|
||||
|
||||
GtkWidget* dlg = gtk_dialog_new_with_buttons(
|
||||
"V4L2 Settings", GTK_WINDOW(data), GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dlg), 320, 75);
|
||||
|
||||
GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
|
||||
GtkWidget* main_hbox = gtk_hbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg_area_box), main_hbox);
|
||||
GtkWidget* right_vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 5);
|
||||
|
||||
GtkWidget* rs_cb = new_combobox("Device:", right_vbox);
|
||||
|
||||
std::vector<std::string> devList = getDevList();
|
||||
int sel_idx = 0;
|
||||
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))
|
||||
{
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), idx);
|
||||
sel_idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
int sel_new;
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(deviceChanged), (gpointer)&sel_new);
|
||||
|
||||
gtk_widget_show_all(dlg);
|
||||
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)))
|
||||
{
|
||||
ret = RESULT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RESULT_CANCELED;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dlg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int V4L2::Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
return GtkConfigure(port, dev_type, data);
|
||||
};
|
||||
|
||||
} // namespace linux_api
|
||||
} // namespace usb_eyetoy
|
||||
|
|
|
@ -17,37 +17,40 @@
|
|||
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
namespace linux_api
|
||||
{
|
||||
namespace linux_api
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
void *start;
|
||||
size_t length;
|
||||
} buffer_t;
|
||||
typedef struct
|
||||
{
|
||||
void* start;
|
||||
size_t length;
|
||||
} buffer_t;
|
||||
|
||||
static const char *APINAME = "V4L2";
|
||||
static const char* APINAME = "V4L2";
|
||||
|
||||
class V4L2 : public VideoDevice
|
||||
{
|
||||
public:
|
||||
V4L2(int port) : mPort(port) {};
|
||||
~V4L2(){};
|
||||
int Open();
|
||||
int Close();
|
||||
int GetImage(uint8_t *buf, int len);
|
||||
int Reset() { return 0; };
|
||||
class V4L2 : public VideoDevice
|
||||
{
|
||||
public:
|
||||
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() {
|
||||
return TEXT("V4L2");
|
||||
}
|
||||
static int Configure(int port, const char *dev_type, void *data);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("V4L2");
|
||||
}
|
||||
static int Configure(int port, const char* dev_type, void* data);
|
||||
|
||||
int Port() { return mPort; }
|
||||
void Port(int port) { mPort = port; }
|
||||
int Port() { return mPort; }
|
||||
void Port(int port) { mPort = port; }
|
||||
|
||||
private:
|
||||
int mPort;
|
||||
};
|
||||
private:
|
||||
int mPort;
|
||||
};
|
||||
|
||||
} // namespace linux_api
|
||||
} // namespace linux_api
|
||||
} // namespace usb_eyetoy
|
||||
|
|
|
@ -23,452 +23,526 @@
|
|||
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
namespace windows_api
|
||||
{
|
||||
namespace windows_api
|
||||
{
|
||||
|
||||
HRESULT DirectShow::CallbackHandler::SampleCB(double time, IMediaSample *sample) {
|
||||
HRESULT hr;
|
||||
unsigned char* buffer;
|
||||
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;
|
||||
hr = sample->GetPointer((BYTE**)&buffer);
|
||||
if (hr != S_OK)
|
||||
return S_OK;
|
||||
|
||||
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 ) {
|
||||
*ppv = (void *) static_cast<ISampleGrabberCB*>( this );
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
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)) {
|
||||
fprintf(stderr, "Error Creating Device Enumerator");
|
||||
return devList;
|
||||
}
|
||||
|
||||
IEnumMoniker *pEnum = 0;
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "You have no video capture hardware");
|
||||
return devList;
|
||||
};
|
||||
|
||||
IMoniker *pMoniker = NULL;
|
||||
while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
|
||||
IPropertyBag *pPropBag;
|
||||
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
|
||||
if (FAILED(hr)) {
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
if (callback)
|
||||
callback(buffer, sample->GetActualDataLength(), BITS_PER_PIXEL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
hr = pPropBag->Read(L"Description", &var, 0);
|
||||
if (FAILED(hr)) {
|
||||
hr = pPropBag->Read(L"FriendlyName", &var, 0);
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
devList.push_back(var.bstrVal);
|
||||
VariantClear(&var);
|
||||
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;
|
||||
}
|
||||
|
||||
pPropBag->Release();
|
||||
pMoniker->Release();
|
||||
}
|
||||
std::vector<std::wstring> getDevList()
|
||||
{
|
||||
std::vector<std::wstring> devList;
|
||||
|
||||
pEnum->Release();
|
||||
CoUninitialize();
|
||||
ICreateDevEnum* pCreateDevEnum = 0;
|
||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCreateDevEnum));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "Error Creating Device Enumerator");
|
||||
return devList;
|
||||
}
|
||||
|
||||
return devList;
|
||||
}
|
||||
IEnumMoniker* pEnum = 0;
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "You have no video capture hardware");
|
||||
return devList;
|
||||
};
|
||||
|
||||
int DirectShow::InitializeDevice(std::wstring selectedDevice) {
|
||||
IMoniker* pMoniker = NULL;
|
||||
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
|
||||
{
|
||||
IPropertyBag* pPropBag;
|
||||
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create the Capture Graph Builder.
|
||||
HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraphBuilder));
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "CoCreateInstance CLSID_CaptureGraphBuilder2 err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
hr = pPropBag->Read(L"Description", &var, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
hr = pPropBag->Read(L"FriendlyName", &var, 0);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
devList.push_back(var.bstrVal);
|
||||
VariantClear(&var);
|
||||
}
|
||||
|
||||
// Create the Filter Graph Manager.
|
||||
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "CoCreateInstance CLSID_FilterGraph err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
pPropBag->Release();
|
||||
pMoniker->Release();
|
||||
}
|
||||
|
||||
hr = pGraphBuilder->SetFiltergraph(pGraph);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "SetFiltergraph err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
pEnum->Release();
|
||||
CoUninitialize();
|
||||
|
||||
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "QueryInterface IID_IMediaControl err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// enumerate all video capture devices
|
||||
ICreateDevEnum *pCreateDevEnum = 0;
|
||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCreateDevEnum));
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "Error Creating Device Enumerator");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IEnumMoniker *pEnum = 0;
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "You have no video capture hardware");
|
||||
return -1;
|
||||
};
|
||||
|
||||
pEnum->Reset();
|
||||
|
||||
IMoniker *pMoniker;
|
||||
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)) {
|
||||
fprintf(stderr, "BindToStorage err : %x\n", hr);
|
||||
goto freeMoniker;
|
||||
return devList;
|
||||
}
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
int DirectShow::InitializeDevice(std::wstring selectedDevice)
|
||||
{
|
||||
|
||||
hr = pPropBag->Read(L"Description", &var, 0);
|
||||
if (FAILED(hr)) {
|
||||
hr = pPropBag->Read(L"FriendlyName", &var, 0);
|
||||
}
|
||||
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) {
|
||||
goto freeVar;
|
||||
}
|
||||
// Create the Capture Graph Builder.
|
||||
HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraphBuilder));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "CoCreateInstance CLSID_CaptureGraphBuilder2 err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//add a filter for the device
|
||||
hr = pGraph->AddSourceFilterForMoniker(pMoniker, NULL, L"sourcefilter", &sourcefilter);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "AddSourceFilterForMoniker err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
// Create the Filter Graph Manager.
|
||||
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "CoCreateInstance CLSID_FilterGraph err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = pGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, sourcefilter, IID_IAMStreamConfig, (void **)&pSourceConfig);
|
||||
if (SUCCEEDED(hr)) {
|
||||
int iCount = 0, iSize = 0;
|
||||
hr = pSourceConfig->GetNumberOfCapabilities(&iCount, &iSize);
|
||||
hr = pGraphBuilder->SetFiltergraph(pGraph);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "SetFiltergraph err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check the size to make sure we pass in the correct structure.
|
||||
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
|
||||
// Use the video capabilities structure.
|
||||
for (int iFormat = 0; iFormat < iCount; iFormat++) {
|
||||
VIDEO_STREAM_CONFIG_CAPS scc;
|
||||
AM_MEDIA_TYPE *pmtConfig;
|
||||
hr = pSourceConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE *)&scc);
|
||||
fprintf(stderr, "GetStreamCaps min=%dx%d max=%dx%d, fmt=%x\n",
|
||||
scc.MinOutputSize.cx, scc.MinOutputSize.cy,
|
||||
scc.MaxOutputSize.cx, scc.MaxOutputSize.cy,
|
||||
pmtConfig->subtype);
|
||||
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "QueryInterface IID_IMediaControl err : %x\n", hr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
if ((pmtConfig->majortype == MEDIATYPE_Video) &&
|
||||
(pmtConfig->formattype == FORMAT_VideoInfo) &&
|
||||
(pmtConfig->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
|
||||
(pmtConfig->pbFormat != NULL)) {
|
||||
// enumerate all video capture devices
|
||||
ICreateDevEnum* pCreateDevEnum = 0;
|
||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCreateDevEnum));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "Error Creating Device Enumerator");
|
||||
return -1;
|
||||
}
|
||||
|
||||
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
|
||||
pVih->bmiHeader.biWidth = 320;
|
||||
pVih->bmiHeader.biHeight = 240;
|
||||
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
|
||||
hr = pSourceConfig->SetFormat(pmtConfig);
|
||||
IEnumMoniker* pEnum = 0;
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "You have no video capture hardware");
|
||||
return -1;
|
||||
};
|
||||
|
||||
pEnum->Reset();
|
||||
|
||||
IMoniker* pMoniker;
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "BindToStorage err : %x\n", hr);
|
||||
goto freeMoniker;
|
||||
}
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
|
||||
hr = pPropBag->Read(L"Description", &var, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
hr = pPropBag->Read(L"FriendlyName", &var, 0);
|
||||
}
|
||||
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)
|
||||
{
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
//add a filter for the device
|
||||
hr = pGraph->AddSourceFilterForMoniker(pMoniker, NULL, L"sourcefilter", &sourcefilter);
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
// Use the video capabilities structure.
|
||||
for (int iFormat = 0; iFormat < iCount; iFormat++)
|
||||
{
|
||||
VIDEO_STREAM_CONFIG_CAPS scc;
|
||||
AM_MEDIA_TYPE* pmtConfig;
|
||||
hr = pSourceConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
|
||||
fprintf(stderr, "GetStreamCaps min=%dx%d max=%dx%d, fmt=%x\n",
|
||||
scc.MinOutputSize.cx, scc.MinOutputSize.cy,
|
||||
scc.MaxOutputSize.cx, scc.MaxOutputSize.cy,
|
||||
pmtConfig->subtype);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if ((pmtConfig->majortype == MEDIATYPE_Video) &&
|
||||
(pmtConfig->formattype == FORMAT_VideoInfo) &&
|
||||
(pmtConfig->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
|
||||
(pmtConfig->pbFormat != NULL))
|
||||
{
|
||||
|
||||
VIDEOINFOHEADER* pVih = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
|
||||
pVih->bmiHeader.biWidth = 320;
|
||||
pVih->bmiHeader.biHeight = 240;
|
||||
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
|
||||
hr = pSourceConfig->SetFormat(pmtConfig);
|
||||
}
|
||||
//DeleteMediaType(pmtConfig);
|
||||
}
|
||||
}
|
||||
//DeleteMediaType(pmtConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Sample Grabber filter.
|
||||
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&samplegrabberfilter));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
fprintf(stderr, "CoCreateInstance CLSID_SampleGrabber err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
hr = pGraph->AddFilter(samplegrabberfilter, L"samplegrabberfilter");
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "QueryInterface err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
AM_MEDIA_TYPE mt;
|
||||
ZeroMemory(&mt, sizeof(mt));
|
||||
mt.majortype = MEDIATYPE_Video;
|
||||
mt.subtype = MEDIASUBTYPE_RGB24;
|
||||
hr = samplegrabber->SetMediaType(&mt);
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "CoCreateInstance CLSID_NullRenderer err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
hr = pGraph->AddFilter(nullrenderer, L"nullrenderer");
|
||||
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))
|
||||
{
|
||||
fprintf(stderr, "RenderStream err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
fprintf(stderr, "ControlStream err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
freeVar:
|
||||
VariantClear(&var);
|
||||
pPropBag->Release();
|
||||
|
||||
freeMoniker:
|
||||
pMoniker->Release();
|
||||
}
|
||||
pEnum->Release();
|
||||
if (sourcefilter == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DirectShow::Start()
|
||||
{
|
||||
HRESULT hr = nullrenderer->Run(0);
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
|
||||
hr = samplegrabberfilter->Run(0);
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
|
||||
hr = sourcefilter->Run(0);
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
}
|
||||
|
||||
void DirectShow::Stop()
|
||||
{
|
||||
HRESULT hr = sourcefilter->Stop();
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
|
||||
hr = samplegrabberfilter->Stop();
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
|
||||
hr = nullrenderer->Stop();
|
||||
if (FAILED(hr))
|
||||
throw hr;
|
||||
}
|
||||
|
||||
buffer_t mpeg_buffer{};
|
||||
std::mutex mpeg_mutex;
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
fprintf(stderr, "dshow_callback: unk format: len=%d bpp=%d\n", len, bitsperpixel);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Sample Grabber filter.
|
||||
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&samplegrabberfilter));
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "CoCreateInstance CLSID_SampleGrabber err : %x\n", hr);
|
||||
goto freeVar;
|
||||
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++)
|
||||
{
|
||||
unsigned char* ptr = rgbData + (y * width + x) * bytesPerPixel;
|
||||
ptr[0] = 255 - y;
|
||||
ptr[1] = y;
|
||||
ptr[2] = 255 - y;
|
||||
}
|
||||
}
|
||||
unsigned char* mpegData = (unsigned char*)calloc(1, width * height * bytesPerPixel);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, width, height, JO_RGB24, JO_NONE, JO_NONE);
|
||||
free(rgbData);
|
||||
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
}
|
||||
|
||||
hr = pGraph->AddFilter(samplegrabberfilter, L"samplegrabberfilter");
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "AddFilter samplegrabberfilter err : %x\n", hr);
|
||||
goto freeVar;
|
||||
DirectShow::DirectShow(int port)
|
||||
{
|
||||
mPort = port;
|
||||
pGraphBuilder = NULL;
|
||||
pGraph = NULL;
|
||||
pControl = NULL;
|
||||
sourcefilter = NULL;
|
||||
samplegrabberfilter = NULL;
|
||||
nullrenderer = NULL;
|
||||
pSourceConfig = NULL;
|
||||
samplegrabber = NULL;
|
||||
callbackhandler = new CallbackHandler();
|
||||
CoInitialize(NULL);
|
||||
}
|
||||
|
||||
//set mediatype on the samplegrabber
|
||||
hr = samplegrabberfilter->QueryInterface(IID_PPV_ARGS(&samplegrabber));
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "QueryInterface err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
AM_MEDIA_TYPE mt;
|
||||
ZeroMemory(&mt, sizeof(mt));
|
||||
mt.majortype = MEDIATYPE_Video;
|
||||
mt.subtype = MEDIASUBTYPE_RGB24;
|
||||
hr = samplegrabber->SetMediaType(&mt);
|
||||
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) {
|
||||
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)) {
|
||||
fprintf(stderr, "CoCreateInstance CLSID_NullRenderer err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
hr = pGraph->AddFilter(nullrenderer, L"nullrenderer");
|
||||
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)) {
|
||||
fprintf(stderr, "RenderStream err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
fprintf(stderr, "ControlStream err : %x\n", hr);
|
||||
goto freeVar;
|
||||
}
|
||||
|
||||
freeVar:
|
||||
VariantClear(&var);
|
||||
pPropBag->Release();
|
||||
|
||||
freeMoniker:
|
||||
pMoniker->Release();
|
||||
}
|
||||
pEnum->Release();
|
||||
if (sourcefilter == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DirectShow::Start() {
|
||||
HRESULT hr = nullrenderer->Run(0);
|
||||
if (FAILED(hr)) throw hr;
|
||||
|
||||
hr = samplegrabberfilter->Run(0);
|
||||
if (FAILED(hr)) throw hr;
|
||||
|
||||
hr = sourcefilter->Run(0);
|
||||
if (FAILED(hr)) throw hr;
|
||||
}
|
||||
|
||||
void DirectShow::Stop() {
|
||||
HRESULT hr = sourcefilter->Stop();
|
||||
if (FAILED(hr)) throw hr;
|
||||
|
||||
hr = samplegrabberfilter->Stop();
|
||||
if (FAILED(hr)) throw hr;
|
||||
|
||||
hr = nullrenderer->Stop();
|
||||
if (FAILED(hr)) throw hr;
|
||||
}
|
||||
|
||||
buffer_t mpeg_buffer {};
|
||||
std::mutex mpeg_mutex;
|
||||
|
||||
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) {
|
||||
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 {
|
||||
fprintf(stderr, "dshow_callback: unk format: len=%d bpp=%d\n", len, bitsperpixel);
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
unsigned char *ptr = rgbData + (y*width+x) * bytesPerPixel;
|
||||
ptr[0] = 255-y;
|
||||
ptr[1] = y;
|
||||
ptr[2] = 255-y;
|
||||
}
|
||||
}
|
||||
unsigned char *mpegData = (unsigned char*) calloc(1, width * height * bytesPerPixel);
|
||||
int mpegLen = jo_write_mpeg(mpegData, rgbData, width, height, JO_RGB24, JO_NONE, JO_NONE);
|
||||
free(rgbData);
|
||||
|
||||
store_mpeg_frame(mpegData, mpegLen);
|
||||
free(mpegData);
|
||||
}
|
||||
|
||||
DirectShow::DirectShow(int port) {
|
||||
mPort = port;
|
||||
pGraphBuilder = NULL;
|
||||
pGraph = NULL;
|
||||
pControl = NULL;
|
||||
sourcefilter = NULL;
|
||||
samplegrabberfilter = NULL;
|
||||
nullrenderer = NULL;
|
||||
pSourceConfig = NULL;
|
||||
samplegrabber = NULL;
|
||||
callbackhandler = new CallbackHandler();
|
||||
CoInitialize(NULL);
|
||||
}
|
||||
|
||||
int DirectShow::Open() {
|
||||
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
|
||||
create_dummy_frame();
|
||||
|
||||
std::wstring selectedDevice;
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), Port(), APINAME, N_DEVICE, selectedDevice);
|
||||
|
||||
int ret = InitializeDevice(selectedDevice);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Camera: cannot find '%ls'\n", selectedDevice.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
pControl->Run();
|
||||
this->Stop();
|
||||
this->SetCallback(dshow_callback);
|
||||
this->Start();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
int DirectShow::Close() {
|
||||
if (sourcefilter != NULL) {
|
||||
this->Stop();
|
||||
pControl->Stop();
|
||||
|
||||
sourcefilter->Release();
|
||||
pSourceConfig->Release();
|
||||
samplegrabberfilter->Release();
|
||||
samplegrabber->Release();
|
||||
nullrenderer->Release();
|
||||
}
|
||||
|
||||
pGraphBuilder->Release();
|
||||
pGraph->Release();
|
||||
pControl->Release();
|
||||
|
||||
if (mpeg_buffer.start != NULL) {
|
||||
free(mpeg_buffer.start);
|
||||
mpeg_buffer.start = NULL;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int DirectShow::GetImage(uint8_t *buf, int len) {
|
||||
mpeg_mutex.lock();
|
||||
int len2 = mpeg_buffer.length;
|
||||
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) {
|
||||
int port;
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CREATE:
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
break;
|
||||
case WM_INITDIALOG: {
|
||||
port = (int)lParam;
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
int DirectShow::Open()
|
||||
{
|
||||
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
|
||||
create_dummy_frame();
|
||||
|
||||
std::wstring selectedDevice;
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), port, APINAME, N_DEVICE, selectedDevice);
|
||||
SendDlgItemMessage(hW, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), Port(), APINAME, N_DEVICE, selectedDevice);
|
||||
|
||||
std::vector<std::wstring> devList = getDevList();
|
||||
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)) {
|
||||
SendDlgItemMessage(hW, IDC_COMBO1, CB_SETCURSEL, i, i);
|
||||
}
|
||||
int ret = InitializeDevice(selectedDevice);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "Camera: cannot find '%ls'\n", selectedDevice.c_str());
|
||||
return -1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
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)) {
|
||||
res = RESULT_FAILED;
|
||||
|
||||
pControl->Run();
|
||||
this->Stop();
|
||||
this->SetCallback(dshow_callback);
|
||||
this->Start();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
int DirectShow::Close()
|
||||
{
|
||||
if (sourcefilter != NULL)
|
||||
{
|
||||
this->Stop();
|
||||
pControl->Stop();
|
||||
|
||||
sourcefilter->Release();
|
||||
pSourceConfig->Release();
|
||||
samplegrabberfilter->Release();
|
||||
samplegrabber->Release();
|
||||
nullrenderer->Release();
|
||||
}
|
||||
|
||||
pGraphBuilder->Release();
|
||||
pGraph->Release();
|
||||
pControl->Release();
|
||||
|
||||
if (mpeg_buffer.start != NULL)
|
||||
{
|
||||
free(mpeg_buffer.start);
|
||||
mpeg_buffer.start = NULL;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int DirectShow::GetImage(uint8_t* buf, int len)
|
||||
{
|
||||
mpeg_mutex.lock();
|
||||
int len2 = mpeg_buffer.length;
|
||||
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)
|
||||
{
|
||||
int port;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
port = (int)lParam;
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
|
||||
std::wstring selectedDevice;
|
||||
LoadSetting(EyeToyWebCamDevice::TypeName(), port, APINAME, N_DEVICE, selectedDevice);
|
||||
SendDlgItemMessage(hW, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
std::vector<std::wstring> devList = getDevList();
|
||||
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))
|
||||
{
|
||||
SendDlgItemMessage(hW, IDC_COMBO1, CB_SETCURSEL, i, i);
|
||||
}
|
||||
EndDialog(hW, res);
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, RESULT_CANCELED);
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
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))
|
||||
{
|
||||
res = RESULT_FAILED;
|
||||
}
|
||||
EndDialog(hW, res);
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, RESULT_CANCELED);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int DirectShow::Configure(int port, const char *dev_type, void *data) {
|
||||
Win32Handles handles = *(Win32Handles *)data;
|
||||
return DialogBoxParam(handles.hInst,
|
||||
MAKEINTRESOURCE(IDD_DLG_EYETOY),
|
||||
handles.hWnd,
|
||||
(DLGPROC)DirectShowDlgProc, port);
|
||||
};
|
||||
int DirectShow::Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
Win32Handles handles = *(Win32Handles*)data;
|
||||
return DialogBoxParam(handles.hInst,
|
||||
MAKEINTRESOURCE(IDD_DLG_EYETOY),
|
||||
handles.hWnd,
|
||||
(DLGPROC)DirectShowDlgProc, port);
|
||||
};
|
||||
|
||||
} // namespace windows_api
|
||||
} // namespace windows_api
|
||||
} // namespace usb_eyetoy
|
||||
|
|
|
@ -22,31 +22,33 @@
|
|||
#include <dshow.h>
|
||||
|
||||
extern "C" {
|
||||
extern GUID IID_ISampleGrabberCB;
|
||||
extern GUID CLSID_SampleGrabber;
|
||||
extern GUID CLSID_NullRenderer;
|
||||
extern GUID IID_ISampleGrabberCB;
|
||||
extern GUID CLSID_SampleGrabber;
|
||||
extern GUID CLSID_NullRenderer;
|
||||
}
|
||||
|
||||
#pragma region qedit.h
|
||||
struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
|
||||
ISampleGrabberCB : IUnknown {
|
||||
virtual HRESULT __stdcall SampleCB (double SampleTime, struct IMediaSample *pSample) = 0;
|
||||
virtual HRESULT __stdcall BufferCB (double SampleTime, unsigned char *pBuffer, long BufferLen) = 0;
|
||||
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 {
|
||||
virtual HRESULT __stdcall SetOneShot (long OneShot) = 0;
|
||||
virtual HRESULT __stdcall SetMediaType (struct _AMMediaType *pType) = 0;
|
||||
virtual HRESULT __stdcall GetConnectedMediaType (struct _AMMediaType *pType) = 0;
|
||||
virtual HRESULT __stdcall SetBufferSamples (long BufferThem) = 0;
|
||||
virtual HRESULT __stdcall GetCurrentBuffer (long *pBufferSize, long *pBuffer) = 0;
|
||||
virtual HRESULT __stdcall GetCurrentSample (struct IMediaSample **ppSample) = 0;
|
||||
virtual HRESULT __stdcall SetCallback (struct ISampleGrabberCB *pCallback, long WhichMethodToCallback) = 0;
|
||||
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;
|
||||
virtual HRESULT __stdcall SetBufferSamples(long BufferThem) = 0;
|
||||
virtual HRESULT __stdcall GetCurrentBuffer(long* pBufferSize, long* pBuffer) = 0;
|
||||
virtual HRESULT __stdcall GetCurrentSample(struct IMediaSample** ppSample) = 0;
|
||||
virtual HRESULT __stdcall SetCallback(struct ISampleGrabberCB* pCallback, long WhichMethodToCallback) = 0;
|
||||
};
|
||||
|
||||
struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37"))
|
||||
SampleGrabber;
|
||||
SampleGrabber;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
@ -65,73 +67,76 @@ SampleGrabber;
|
|||
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
namespace windows_api
|
||||
{
|
||||
|
||||
typedef void (*DShowVideoCaptureCallback)(unsigned char *data, int len, int bitsperpixel);
|
||||
|
||||
typedef struct {
|
||||
void *start = NULL;
|
||||
size_t length = 0;
|
||||
} buffer_t;
|
||||
|
||||
static const char *APINAME = "DirectShow";
|
||||
|
||||
class DirectShow : public VideoDevice {
|
||||
public:
|
||||
DirectShow(int port);
|
||||
~DirectShow() {}
|
||||
int Open();
|
||||
int Close();
|
||||
int GetImage(uint8_t *buf, int len);
|
||||
int Reset() { return 0; };
|
||||
|
||||
static const TCHAR *Name() {
|
||||
return TEXT("DirectShow");
|
||||
}
|
||||
static int Configure(int port, const char *dev_type, void *data);
|
||||
|
||||
int Port() { return mPort; }
|
||||
void Port(int port) { mPort = port; }
|
||||
|
||||
protected:
|
||||
void SetCallback(DShowVideoCaptureCallback cb) { callbackhandler->SetCallback(cb); }
|
||||
void Start();
|
||||
void Stop();
|
||||
int InitializeDevice(std::wstring selectedDevice);
|
||||
|
||||
private:
|
||||
int mPort;
|
||||
|
||||
ICaptureGraphBuilder2 *pGraphBuilder;
|
||||
IFilterGraph2 *pGraph;
|
||||
IMediaControl *pControl;
|
||||
|
||||
IBaseFilter *sourcefilter;
|
||||
IAMStreamConfig *pSourceConfig;
|
||||
IBaseFilter *samplegrabberfilter;
|
||||
ISampleGrabber *samplegrabber;
|
||||
IBaseFilter *nullrenderer;
|
||||
|
||||
class CallbackHandler : public ISampleGrabberCB
|
||||
namespace windows_api
|
||||
{
|
||||
public:
|
||||
CallbackHandler() { callback = 0; }
|
||||
~CallbackHandler() {}
|
||||
|
||||
void SetCallback(DShowVideoCaptureCallback cb) { callback = cb; }
|
||||
typedef void (*DShowVideoCaptureCallback)(unsigned char* data, int len, int bitsperpixel);
|
||||
|
||||
virtual HRESULT __stdcall SampleCB(double time, IMediaSample *sample);
|
||||
virtual HRESULT __stdcall BufferCB(double time, BYTE *buffer, long len) { return S_OK; }
|
||||
virtual HRESULT __stdcall QueryInterface(REFIID iid, LPVOID *ppv);
|
||||
virtual ULONG __stdcall AddRef() { return 1; }
|
||||
virtual ULONG __stdcall Release() { return 2; }
|
||||
typedef struct
|
||||
{
|
||||
void* start = NULL;
|
||||
size_t length = 0;
|
||||
} buffer_t;
|
||||
|
||||
private:
|
||||
DShowVideoCaptureCallback callback;
|
||||
static const char* APINAME = "DirectShow";
|
||||
|
||||
} * callbackhandler;
|
||||
};
|
||||
class DirectShow : public VideoDevice
|
||||
{
|
||||
public:
|
||||
DirectShow(int port);
|
||||
~DirectShow() {}
|
||||
int Open();
|
||||
int Close();
|
||||
int GetImage(uint8_t* buf, int len);
|
||||
int Reset() { return 0; };
|
||||
|
||||
} // namespace windows_api
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("DirectShow");
|
||||
}
|
||||
static int Configure(int port, const char* dev_type, void* data);
|
||||
|
||||
int Port() { return mPort; }
|
||||
void Port(int port) { mPort = port; }
|
||||
|
||||
protected:
|
||||
void SetCallback(DShowVideoCaptureCallback cb) { callbackhandler->SetCallback(cb); }
|
||||
void Start();
|
||||
void Stop();
|
||||
int InitializeDevice(std::wstring selectedDevice);
|
||||
|
||||
private:
|
||||
int mPort;
|
||||
|
||||
ICaptureGraphBuilder2* pGraphBuilder;
|
||||
IFilterGraph2* pGraph;
|
||||
IMediaControl* pControl;
|
||||
|
||||
IBaseFilter* sourcefilter;
|
||||
IAMStreamConfig* pSourceConfig;
|
||||
IBaseFilter* samplegrabberfilter;
|
||||
ISampleGrabber* samplegrabber;
|
||||
IBaseFilter* nullrenderer;
|
||||
|
||||
class CallbackHandler : public ISampleGrabberCB
|
||||
{
|
||||
public:
|
||||
CallbackHandler() { callback = 0; }
|
||||
~CallbackHandler() {}
|
||||
|
||||
void SetCallback(DShowVideoCaptureCallback cb) { callback = cb; }
|
||||
|
||||
virtual HRESULT __stdcall SampleCB(double time, IMediaSample* sample);
|
||||
virtual HRESULT __stdcall BufferCB(double time, BYTE* buffer, long len) { return S_OK; }
|
||||
virtual HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppv);
|
||||
virtual ULONG __stdcall AddRef() { return 1; }
|
||||
virtual ULONG __stdcall Release() { return 2; }
|
||||
|
||||
private:
|
||||
DShowVideoCaptureCallback callback;
|
||||
|
||||
} * callbackhandler;
|
||||
};
|
||||
|
||||
} // namespace windows_api
|
||||
} // namespace usb_eyetoy
|
||||
|
|
|
@ -34,38 +34,163 @@
|
|||
#include "jo_mpeg.h"
|
||||
|
||||
// Huffman tables
|
||||
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_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,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}},
|
||||
{
|
||||
{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}},
|
||||
};
|
||||
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 };
|
||||
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 {
|
||||
unsigned char *buf_ptr;
|
||||
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;
|
||||
|
@ -86,48 +212,52 @@ static void jo_DCT(float *d0, float *d1, float *d2, float *d3, float *d4, float
|
|||
float tmp4 = *d3 - *d4;
|
||||
|
||||
// Even part
|
||||
float tmp10 = tmp0 + tmp3; // phase 2
|
||||
float tmp10 = tmp0 + tmp3; // phase 2
|
||||
float tmp13 = tmp0 - tmp3;
|
||||
float tmp11 = tmp1 + tmp2;
|
||||
float tmp12 = tmp1 - tmp2;
|
||||
|
||||
*d0 = tmp10 + tmp11; // phase 3
|
||||
*d0 = tmp10 + tmp11; // phase 3
|
||||
*d4 = tmp10 - tmp11;
|
||||
|
||||
float z1 = (tmp12 + tmp13) * 0.707106781f; // c4
|
||||
*d2 = tmp13 + z1; // phase 5
|
||||
*d2 = tmp13 + z1; // phase 5
|
||||
*d6 = tmp13 - z1;
|
||||
|
||||
// Odd part
|
||||
tmp10 = tmp4 + tmp5; // phase 2
|
||||
tmp10 = tmp4 + tmp5; // phase 2
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
// The rotator is modified from fig 4-8 to avoid extra negations.
|
||||
float z5 = (tmp10 - tmp12) * 0.382683433f; // c6
|
||||
float z2 = tmp10 * 0.541196100f + z5; // c2-c6
|
||||
float z4 = tmp12 * 1.306562965f + z5; // c2+c6
|
||||
float z3 = tmp11 * 0.707106781f; // c4
|
||||
float z2 = tmp10 * 0.541196100f + z5; // c2-c6
|
||||
float z4 = tmp12 * 1.306562965f + z5; // c2+c6
|
||||
float z3 = tmp11 * 0.707106781f; // c4
|
||||
|
||||
float z11 = tmp7 + z3; // phase 5
|
||||
float z11 = tmp7 + z3; // phase 5
|
||||
float z13 = tmp7 - z3;
|
||||
|
||||
*d5 = z13 + z2; // phase 6
|
||||
*d5 = z13 + z2; // phase 6
|
||||
*d3 = z13 - z2;
|
||||
*d1 = z11 + z4;
|
||||
*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) {
|
||||
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]);
|
||||
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) {
|
||||
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]);
|
||||
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) {
|
||||
float v = A[i]*s_jo_quantTbl[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) {
|
||||
code = s_jo_HTAC[run][aAC-1][0];
|
||||
size = s_jo_HTAC[run][aAC-1][1];
|
||||
if (AC < 0) code += 1;
|
||||
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(!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;
|
||||
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 {
|
||||
jo_writeBits(&bits, 8, 5); // quantiser_scale_code = 8
|
||||
}
|
||||
else
|
||||
{
|
||||
jo_writeBits(&bits, 0b1, 1); // macroblock_address_increment
|
||||
jo_writeBits(&bits, 0b1, 1); // macroblock_type = intra
|
||||
}
|
||||
|
@ -195,87 +343,113 @@ 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) {
|
||||
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;
|
||||
const unsigned char *c = raw + y*width*4+x*4;
|
||||
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;
|
||||
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;
|
||||
CBx[i] = (-0.299f*r - 0.587f*g + 0.886f*b) * (224.f/255) + 128;
|
||||
CRx[i] = (0.701f*r - 0.587f*g - 0.114f*b) * (224.f/255) + 128;
|
||||
Y[i] = (0.299f * r + 0.587f * g + 0.114f * b) * (219.f / 255) + 16;
|
||||
CBx[i] = (-0.299f * r - 0.587f * g + 0.886f * b) * (224.f / 255) + 128;
|
||||
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) {
|
||||
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;
|
||||
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) {
|
||||
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;
|
||||
const unsigned char *c = raw + y*width*3+x*3;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
CBx[i] = (-0.299f*r - 0.587f*g + 0.886f*b) * (224.f/255) + 128;
|
||||
CRx[i] = (0.701f*r - 0.587f*g - 0.114f*b) * (224.f/255) + 128;
|
||||
Y[i] = (0.299f * r + 0.587f * g + 0.114f * b) * (219.f / 255) + 16;
|
||||
CBx[i] = (-0.299f * r - 0.587f * g + 0.886f * b) * (224.f / 255) + 128;
|
||||
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) {
|
||||
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;
|
||||
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) {
|
||||
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;
|
||||
const unsigned char *c = raw + y*width*2+x*2-2;
|
||||
if (flipx) {
|
||||
Y[i+1] = c[0];
|
||||
CB[i/4] = c[1];
|
||||
Y[i] = c[2];
|
||||
CR[i/4] = c[3];
|
||||
} else {
|
||||
Y[i] = c[2];
|
||||
CB[i/4] = c[3];
|
||||
Y[i+1] = c[4];
|
||||
CR[i/4] = c[5];
|
||||
}
|
||||
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;
|
||||
const unsigned char* c = raw + y * width * 2 + x * 2 - 2;
|
||||
if (flipx)
|
||||
{
|
||||
Y[i + 1] = c[0];
|
||||
CB[i / 4] = c[1];
|
||||
Y[i] = c[2];
|
||||
CR[i / 4] = c[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Y[i] = c[2];
|
||||
CB[i / 4] = c[3];
|
||||
Y[i + 1] = c[4];
|
||||
CR[i / 4] = c[5];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
int j = (i&7)+(i&56)*2 + k1*8*16 + k2*8;
|
||||
memcpy(block+i, Y+j, 8*sizeof(Y[0]));
|
||||
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]));
|
||||
}
|
||||
lastDCY = jo_processDU(&bits, block, s_jo_HTDC_Y, lastDCY);
|
||||
}
|
||||
|
|
|
@ -17,19 +17,21 @@
|
|||
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,
|
||||
} jo_mpeg_flip_t;
|
||||
|
||||
unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *rgbx, int width, int height, int format, int flipx, int flipy);
|
||||
unsigned long jo_write_mpeg(unsigned char* mpeg_buf, const unsigned char* rgbx, int width, int height, int format, int flipx, int flipy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,9 +11,9 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define JPGD_NORETURN __declspec(noreturn)
|
||||
#define JPGD_NORETURN __declspec(noreturn)
|
||||
#elif defined(__GNUC__)
|
||||
#define JPGD_NORETURN __attribute__ ((noreturn))
|
||||
#define JPGD_NORETURN __attribute__((noreturn))
|
||||
#else
|
||||
#define JPGD_NORETURN
|
||||
#endif
|
||||
|
@ -23,11 +23,11 @@
|
|||
|
||||
namespace jpgd
|
||||
{
|
||||
typedef unsigned char uint8;
|
||||
typedef signed short int16;
|
||||
typedef unsigned char uint8;
|
||||
typedef signed short int16;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint;
|
||||
typedef signed int int32;
|
||||
typedef unsigned int uint;
|
||||
typedef signed int int32;
|
||||
|
||||
// Loads a JPEG image from a memory buffer or a file.
|
||||
// req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
|
||||
|
@ -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.
|
||||
|
@ -59,8 +86,8 @@ namespace jpgd
|
|||
class jpeg_decoder_stream
|
||||
{
|
||||
public:
|
||||
jpeg_decoder_stream() { }
|
||||
virtual ~jpeg_decoder_stream() { }
|
||||
jpeg_decoder_stream() {}
|
||||
virtual ~jpeg_decoder_stream() {}
|
||||
|
||||
// The read() method is called when the internal input buffer is empty.
|
||||
// Parameters:
|
||||
|
@ -76,7 +103,7 @@ namespace jpgd
|
|||
class jpeg_decoder_file_stream : public jpeg_decoder_stream
|
||||
{
|
||||
jpeg_decoder_file_stream(const jpeg_decoder_file_stream&);
|
||||
jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&);
|
||||
jpeg_decoder_file_stream& operator=(const jpeg_decoder_file_stream&);
|
||||
|
||||
FILE* m_pFile;
|
||||
bool m_eof_flag, m_error_flag;
|
||||
|
@ -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() { }
|
||||
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;
|
||||
|
@ -142,7 +191,7 @@ namespace jpgd
|
|||
int begin_decoding();
|
||||
|
||||
// Returns the next scan line.
|
||||
// For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
|
||||
// For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
|
||||
// Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
|
||||
// Returns JPGD_SUCCESS if a scan line has been returned.
|
||||
// Returns JPGD_DONE if all scan lines have been returned.
|
||||
|
@ -164,17 +213,17 @@ namespace jpgd
|
|||
|
||||
private:
|
||||
jpeg_decoder(const jpeg_decoder&);
|
||||
jpeg_decoder& operator =(const jpeg_decoder&);
|
||||
jpeg_decoder& operator=(const jpeg_decoder&);
|
||||
|
||||
typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int);
|
||||
|
||||
struct huff_tables
|
||||
{
|
||||
bool ac_table;
|
||||
uint look_up[256];
|
||||
uint look_up2[256];
|
||||
uint look_up[256];
|
||||
uint look_up2[256];
|
||||
uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH];
|
||||
uint tree[JPGD_HUFF_TREE_MAX_LENGTH];
|
||||
uint tree[JPGD_HUFF_TREE_MAX_LENGTH];
|
||||
};
|
||||
|
||||
struct coeff_buf
|
||||
|
@ -214,26 +263,26 @@ namespace jpgd
|
|||
int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
|
||||
int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
|
||||
int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
|
||||
int m_comps_in_scan; // # of components in scan
|
||||
int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
|
||||
int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
|
||||
int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
|
||||
int m_spectral_start; // spectral selection start
|
||||
int m_spectral_end; // spectral selection end
|
||||
int m_successive_low; // successive approximation low
|
||||
int m_successive_high; // successive approximation high
|
||||
int m_max_mcu_x_size; // MCU's max. X size in pixels
|
||||
int m_max_mcu_y_size; // MCU's max. Y size in pixels
|
||||
int m_comps_in_scan; // # of components in scan
|
||||
int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
|
||||
int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
|
||||
int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
|
||||
int m_spectral_start; // spectral selection start
|
||||
int m_spectral_end; // spectral selection end
|
||||
int m_successive_low; // successive approximation low
|
||||
int m_successive_high; // successive approximation high
|
||||
int m_max_mcu_x_size; // MCU's max. X size in pixels
|
||||
int m_max_mcu_y_size; // MCU's max. Y size in pixels
|
||||
int m_blocks_per_mcu;
|
||||
int m_max_blocks_per_row;
|
||||
int m_mcus_per_row, m_mcus_per_col;
|
||||
int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
|
||||
int m_total_lines_left; // total # lines left in image
|
||||
int m_mcu_lines_left; // total # lines left in this MCU
|
||||
int m_total_lines_left; // total # lines left in image
|
||||
int m_mcu_lines_left; // total # lines left in this MCU
|
||||
int m_num_buffered_scanlines;
|
||||
int m_real_dest_bytes_per_scan_line;
|
||||
int m_dest_bytes_per_scan_line; // rounded up
|
||||
int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
|
||||
int m_dest_bytes_per_scan_line; // rounded up
|
||||
int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
|
||||
huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
|
||||
coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
|
||||
coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
|
||||
|
@ -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);
|
||||
|
|
|
@ -24,26 +24,26 @@
|
|||
#include <immintrin.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
||||
#define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
||||
#else
|
||||
#define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
#define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
#endif
|
||||
|
||||
#define BITS_INV_ACC 4
|
||||
#define SHIFT_INV_ROW 16 - BITS_INV_ACC
|
||||
#define SHIFT_INV_COL 1 + BITS_INV_ACC
|
||||
const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
|
||||
const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
|
||||
const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round
|
||||
const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
|
||||
const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
|
||||
const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round
|
||||
|
||||
JPGD_SIMD_ALIGN(short, shortM128_one_corr[8]) = {1, 1, 1, 1, 1, 1, 1, 1};
|
||||
JPGD_SIMD_ALIGN(short, shortM128_round_inv_row[8]) = {IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0};
|
||||
JPGD_SIMD_ALIGN(short, shortM128_round_inv_col[8]) = {IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL};
|
||||
JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8])= {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR};
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8]) = {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR};
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5
|
||||
JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195}; // cos * (2<<16) + 0.5
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Table for rows 0,4 - constants are multiplied on cos_4_16
|
||||
|
@ -56,22 +56,22 @@ JPGD_SIMD_ALIGN(short, shortM128_tab_i_04[]) = {
|
|||
16384, -8867, 16384, -21407, // w13 w12 w09 w08
|
||||
16384, 8867, -16384, -21407, // w07 w06 w03 w02
|
||||
-16384, 21407, 16384, -8867, // w15 w14 w11 w10
|
||||
22725, 19266, 19266, -4520, // w21 w20 w17 w16
|
||||
22725, 19266, 19266, -4520, // w21 w20 w17 w16
|
||||
12873, -22725, 4520, -12873, // w29 w28 w25 w24
|
||||
12873, 4520, -22725, -12873, // w23 w22 w19 w18
|
||||
4520, 19266, 19266, -22725}; // w31 w30 w27 w26
|
||||
|
||||
// Table for rows 1,7 - constants are multiplied on cos_1_16
|
||||
// Table for rows 1,7 - constants are multiplied on cos_1_16
|
||||
//movq -> w05 w04 w01 w00
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tab_i_17[]) = {
|
||||
22725, 29692, 22725, 12299,
|
||||
22725, -12299, 22725, -29692, // w13 w12 w09 w08
|
||||
22725, 12299, -22725, -29692, // w07 w06 w03 w02
|
||||
-22725, 29692, 22725, -12299, // w15 w14 w11 w10
|
||||
31521, 26722, 26722, -6270, // w21 w20 w17 w16
|
||||
17855, -31521, 6270, -17855, // w29 w28 w25 w24
|
||||
17855, 6270, -31521, -17855, // w23 w22 w19 w18
|
||||
6270, 26722, 26722, -31521}; // w31 w30 w27 w26
|
||||
31521, 26722, 26722, -6270, // w21 w20 w17 w16
|
||||
17855, -31521, 6270, -17855, // w29 w28 w25 w24
|
||||
17855, 6270, -31521, -17855, // w23 w22 w19 w18
|
||||
6270, 26722, 26722, -31521}; // w31 w30 w27 w26
|
||||
|
||||
// Table for rows 2,6 - constants are multiplied on cos_2_16
|
||||
//movq -> w05 w04 w01 w00
|
||||
|
@ -80,10 +80,10 @@ JPGD_SIMD_ALIGN(short, shortM128_tab_i_26[]) = {
|
|||
21407, -11585, 21407, -27969, // w13 w12 w09 w08
|
||||
21407, 11585, -21407, -27969, // w07 w06 w03 w02
|
||||
-21407, 27969, 21407, -11585, // w15 w14 w11 w10
|
||||
29692, 25172, 25172, -5906, // w21 w20 w17 w16
|
||||
16819, -29692, 5906, -16819, // w29 w28 w25 w24
|
||||
16819, 5906, -29692, -16819, // w23 w22 w19 w18
|
||||
5906, 25172, 25172, -29692}; // w31 w30 w27 w26
|
||||
29692, 25172, 25172, -5906, // w21 w20 w17 w16
|
||||
16819, -29692, 5906, -16819, // w29 w28 w25 w24
|
||||
16819, 5906, -29692, -16819, // w23 w22 w19 w18
|
||||
5906, 25172, 25172, -29692}; // w31 w30 w27 w26
|
||||
// Table for rows 3,5 - constants are multiplied on cos_3_16
|
||||
//movq -> w05 w04 w01 w00
|
||||
JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = {
|
||||
|
@ -91,28 +91,28 @@ JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = {
|
|||
19266, -10426, 19266, -25172, // w13 w12 w09 w08
|
||||
19266, 10426, -19266, -25172, // w07 w06 w03 w02
|
||||
-19266, 25172, 19266, -10426, // w15 w14 w11 w10
|
||||
26722, 22654, 22654, -5315, // w21 w20 w17 w16
|
||||
15137, -26722, 5315, -15137, // w29 w28 w25 w24
|
||||
15137, 5315, -26722, -15137, // w23 w22 w19 w18
|
||||
5315, 22654, 22654, -26722}; // w31 w30 w27 w26
|
||||
26722, 22654, 22654, -5315, // w21 w20 w17 w16
|
||||
15137, -26722, 5315, -15137, // w29 w28 w25 w24
|
||||
15137, 5315, -26722, -15137, // w23 w22 w19 w18
|
||||
5315, 22654, 22654, -26722}; // w31 w30 w27 w26
|
||||
|
||||
JPGD_SIMD_ALIGN(short, shortM128_128[8]) = { 128, 128, 128, 128, 128, 128, 128, 128 };
|
||||
JPGD_SIMD_ALIGN(short, shortM128_128[8]) = {128, 128, 128, 128, 128, 128, 128, 128};
|
||||
|
||||
void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
||||
void idctSSEShortU8(const short* pInput, uint8_t* pOutputUB)
|
||||
{
|
||||
__m128i r_xmm0, r_xmm4;
|
||||
__m128i r_xmm1, r_xmm2, r_xmm3, r_xmm5, r_xmm6, r_xmm7;
|
||||
__m128i row0, row1, row2, row3, row4, row5, row6, row7;
|
||||
short * pTab_i_04 = shortM128_tab_i_04;
|
||||
short * pTab_i_26 = shortM128_tab_i_26;
|
||||
short* pTab_i_04 = shortM128_tab_i_04;
|
||||
short* pTab_i_26 = shortM128_tab_i_26;
|
||||
|
||||
//Get pointers for this input and output
|
||||
pTab_i_04 = shortM128_tab_i_04;
|
||||
pTab_i_26 = shortM128_tab_i_26;
|
||||
|
||||
//Row 1 and Row 3
|
||||
r_xmm0 = _mm_load_si128((__m128i *) pInput);
|
||||
r_xmm4 = _mm_load_si128((__m128i *) (&pInput[2*8]));
|
||||
r_xmm0 = _mm_load_si128((__m128i*)pInput);
|
||||
r_xmm4 = _mm_load_si128((__m128i*)(&pInput[2 * 8]));
|
||||
|
||||
// *** Work on the data in xmm0
|
||||
//low shuffle mask = 0xd8 = 11 01 10 00
|
||||
|
@ -121,58 +121,58 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
|
||||
// copy short 2 and short 0 to all locations
|
||||
r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
|
||||
|
||||
|
||||
// add to those copies
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i*)pTab_i_04));
|
||||
|
||||
// shuffle mask = 0x55 = 01 01 01 01
|
||||
// copy short 3 and short 1 to all locations
|
||||
r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
|
||||
|
||||
|
||||
// high shuffle mask = 0xd8 = 11 01 10 00
|
||||
// get short 6 and short 4 into bit positions 64-95
|
||||
// get short 7 and short 5 into bit positions 96-127
|
||||
r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
|
||||
|
||||
|
||||
// add to short 3 and short 1
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
|
||||
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i*)&pTab_i_04[16]));
|
||||
|
||||
// shuffle mask = 0xaa = 10 10 10 10
|
||||
// copy short 6 and short 4 to all locations
|
||||
r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
|
||||
|
||||
|
||||
// shuffle mask = 0xaa = 11 11 11 11
|
||||
// copy short 7 and short 5 to all locations
|
||||
r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
|
||||
|
||||
|
||||
// add to short 6 and short 4
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
|
||||
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i*)&pTab_i_04[8]));
|
||||
|
||||
// *** Work on the data in xmm4
|
||||
// high shuffle mask = 0xd8 11 01 10 00
|
||||
// get short 6 and short 4 into bit positions 64-95
|
||||
// get short 7 and short 5 into bit positions 96-127
|
||||
r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
|
||||
|
||||
|
||||
// (xmm0 short 2 and short 0 plus pSi) + some constants
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i*)&pTab_i_04[24]));
|
||||
r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
|
||||
r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i*)&shortM128_tab_i_26[0]));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
|
||||
r_xmm2 = r_xmm1;
|
||||
r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i*)&shortM128_tab_i_26[8]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
|
||||
r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
|
||||
r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i*)&shortM128_tab_i_26[16]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
|
||||
r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i*)&shortM128_tab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
|
||||
r_xmm6 = r_xmm5;
|
||||
r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
|
||||
|
@ -187,37 +187,37 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
row2 = _mm_packs_epi32(r_xmm4, r_xmm6);
|
||||
|
||||
//Row 5 and row 7
|
||||
r_xmm0 = _mm_load_si128((__m128i *) (&pInput[4*8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i *) (&pInput[6*8]));
|
||||
r_xmm0 = _mm_load_si128((__m128i*)(&pInput[4 * 8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i*)(&pInput[6 * 8]));
|
||||
|
||||
r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
|
||||
r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i*)pTab_i_04));
|
||||
r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
|
||||
r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i*)&pTab_i_04[16]));
|
||||
r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
|
||||
r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i*)&pTab_i_04[8]));
|
||||
r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i*)&pTab_i_04[24]));
|
||||
r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
|
||||
r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i*)&shortM128_tab_i_26[0]));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
|
||||
r_xmm2 = r_xmm1;
|
||||
r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i*)&shortM128_tab_i_26[8]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
|
||||
r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
|
||||
r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i*)&shortM128_tab_i_26[16]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
|
||||
r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i*)&shortM128_tab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
|
||||
r_xmm6 = r_xmm5;
|
||||
r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
|
||||
|
@ -234,37 +234,37 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
//Row 4 and row 2
|
||||
pTab_i_04 = shortM128_tab_i_35;
|
||||
pTab_i_26 = shortM128_tab_i_17;
|
||||
r_xmm0 = _mm_load_si128((__m128i *) (&pInput[3*8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i *) (&pInput[1*8]));
|
||||
r_xmm0 = _mm_load_si128((__m128i*)(&pInput[3 * 8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i*)(&pInput[1 * 8]));
|
||||
|
||||
r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
|
||||
r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i*)pTab_i_04));
|
||||
r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
|
||||
r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i*)&pTab_i_04[16]));
|
||||
r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
|
||||
r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i*)&pTab_i_04[8]));
|
||||
r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i*)&pTab_i_04[24]));
|
||||
r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
|
||||
r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i*)&pTab_i_26[0]));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
|
||||
r_xmm2 = r_xmm1;
|
||||
r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i*)&pTab_i_26[8]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
|
||||
r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
|
||||
r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i*)&pTab_i_26[16]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
|
||||
r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i*)&pTab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
|
||||
r_xmm6 = r_xmm5;
|
||||
r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
|
||||
|
@ -279,37 +279,37 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
row1 = _mm_packs_epi32(r_xmm4, r_xmm6);
|
||||
|
||||
//Row 6 and row 8
|
||||
r_xmm0 = _mm_load_si128((__m128i *) (&pInput[5*8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i *) (&pInput[7*8]));
|
||||
r_xmm0 = _mm_load_si128((__m128i*)(&pInput[5 * 8]));
|
||||
r_xmm4 = _mm_load_si128((__m128i*)(&pInput[7 * 8]));
|
||||
|
||||
r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
|
||||
r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
|
||||
r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i*)pTab_i_04));
|
||||
r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
|
||||
r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
|
||||
r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i*)&pTab_i_04[16]));
|
||||
r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
|
||||
r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
|
||||
r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i*)&pTab_i_04[8]));
|
||||
r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
|
||||
r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i*)&pTab_i_04[24]));
|
||||
r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
|
||||
r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
|
||||
r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i*)&pTab_i_26[0]));
|
||||
r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
|
||||
r_xmm2 = r_xmm1;
|
||||
r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
|
||||
r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i*)&pTab_i_26[8]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
|
||||
r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
|
||||
r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
|
||||
r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i*)&pTab_i_26[16]));
|
||||
r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
|
||||
r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i*)shortM128_round_inv_row));
|
||||
r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i*)&pTab_i_26[24]));
|
||||
r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
|
||||
r_xmm6 = r_xmm5;
|
||||
r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
|
||||
|
@ -323,13 +323,13 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
|
||||
row7 = _mm_packs_epi32(r_xmm4, r_xmm6);
|
||||
|
||||
r_xmm1 = _mm_load_si128((__m128i *) shortM128_tg_3_16);
|
||||
r_xmm1 = _mm_load_si128((__m128i*)shortM128_tg_3_16);
|
||||
r_xmm2 = row5;
|
||||
r_xmm3 = row3;
|
||||
r_xmm0 = _mm_mulhi_epi16(row5, r_xmm1);
|
||||
|
||||
r_xmm1 = _mm_mulhi_epi16(r_xmm1, r_xmm3);
|
||||
r_xmm5 = _mm_load_si128((__m128i *) shortM128_tg_1_16);
|
||||
r_xmm5 = _mm_load_si128((__m128i*)shortM128_tg_1_16);
|
||||
r_xmm6 = row7;
|
||||
r_xmm4 = _mm_mulhi_epi16(row7, r_xmm5);
|
||||
|
||||
|
@ -339,7 +339,7 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm7 = row6;
|
||||
|
||||
r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm3);
|
||||
r_xmm3 = _mm_load_si128((__m128i *) shortM128_tg_2_16);
|
||||
r_xmm3 = _mm_load_si128((__m128i*)shortM128_tg_2_16);
|
||||
r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm1);
|
||||
r_xmm7 = _mm_mulhi_epi16(r_xmm7, r_xmm3);
|
||||
r_xmm1 = r_xmm0;
|
||||
|
@ -347,11 +347,11 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm6);
|
||||
r_xmm4 = _mm_adds_epi16(r_xmm4, row1);
|
||||
r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm4);
|
||||
r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i *) shortM128_one_corr));
|
||||
r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i*)shortM128_one_corr));
|
||||
r_xmm4 = _mm_subs_epi16(r_xmm4, r_xmm1);
|
||||
r_xmm6 = r_xmm5;
|
||||
r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm2);
|
||||
r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_one_corr));
|
||||
r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i*)shortM128_one_corr));
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
|
||||
|
||||
//Intermediate results, needed later
|
||||
|
@ -359,9 +359,9 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
temp7 = r_xmm0;
|
||||
|
||||
r_xmm1 = r_xmm4;
|
||||
r_xmm0 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
|
||||
r_xmm0 = _mm_load_si128((__m128i*)shortM128_cos_4_16);
|
||||
r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm5);
|
||||
r_xmm2 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
|
||||
r_xmm2 = _mm_load_si128((__m128i*)shortM128_cos_4_16);
|
||||
r_xmm2 = _mm_mulhi_epi16(r_xmm2, r_xmm4);
|
||||
|
||||
//Intermediate results, needed later
|
||||
|
@ -377,24 +377,24 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm6 = _mm_subs_epi16(r_xmm6, row4);
|
||||
r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm2);
|
||||
|
||||
r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i *) shortM128_one_corr));
|
||||
r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i*)shortM128_one_corr));
|
||||
r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm1);
|
||||
r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i *) shortM128_one_corr));
|
||||
r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i*)shortM128_one_corr));
|
||||
|
||||
r_xmm2 = r_xmm5;
|
||||
r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm7);
|
||||
r_xmm1 = r_xmm6;
|
||||
r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_round_inv_col));
|
||||
r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i*)shortM128_round_inv_col));
|
||||
r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm7);
|
||||
r_xmm7 = temp7;
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm3);
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i *) shortM128_round_inv_col));
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i*)shortM128_round_inv_col));
|
||||
r_xmm7 = _mm_adds_epi16(r_xmm7, r_xmm5);
|
||||
r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
|
||||
r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm3);
|
||||
r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i *) shortM128_round_inv_corr));
|
||||
r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i*)shortM128_round_inv_corr));
|
||||
r_xmm3 = r_xmm6;
|
||||
r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i *) shortM128_round_inv_corr));
|
||||
r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i*)shortM128_round_inv_corr));
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm4);
|
||||
|
||||
//Store results for row 0
|
||||
|
@ -406,7 +406,7 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm0);
|
||||
|
||||
//Store results for row 1
|
||||
//_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6);
|
||||
//_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6);
|
||||
__m128i r1 = r_xmm6;
|
||||
|
||||
r_xmm1 = _mm_srai_epi16(r_xmm1, SHIFT_INV_COL);
|
||||
|
@ -415,24 +415,24 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
|
||||
|
||||
//Store results for row 2
|
||||
//_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1);
|
||||
//_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1);
|
||||
__m128i r2 = r_xmm1;
|
||||
|
||||
r_xmm5 = _mm_subs_epi16(r_xmm5, temp7);
|
||||
r_xmm5 = _mm_subs_epi16(r_xmm5, temp7);
|
||||
r_xmm5 = _mm_srai_epi16(r_xmm5, SHIFT_INV_COL);
|
||||
|
||||
//Store results for row 7
|
||||
//_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5);
|
||||
//_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5);
|
||||
__m128i r7 = r_xmm5;
|
||||
|
||||
r_xmm3 = _mm_subs_epi16(r_xmm3, r_xmm4);
|
||||
r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
|
||||
r_xmm2 = _mm_subs_epi16(r_xmm2, temp3);
|
||||
r_xmm2 = _mm_subs_epi16(r_xmm2, temp3);
|
||||
r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL);
|
||||
r_xmm2 = _mm_srai_epi16(r_xmm2, SHIFT_INV_COL);
|
||||
|
||||
//Store results for row 3
|
||||
//_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6);
|
||||
//_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6);
|
||||
__m128i r3 = r_xmm6;
|
||||
|
||||
r_xmm3 = _mm_srai_epi16(r_xmm3, SHIFT_INV_COL);
|
||||
|
@ -446,17 +446,17 @@ void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
|
|||
__m128i r5 = r_xmm7;
|
||||
__m128i r6 = r_xmm3;
|
||||
|
||||
r0 = _mm_add_epi16(*(const __m128i *)shortM128_128, r0);
|
||||
r1 = _mm_add_epi16(*(const __m128i *)shortM128_128, r1);
|
||||
r2 = _mm_add_epi16(*(const __m128i *)shortM128_128, r2);
|
||||
r3 = _mm_add_epi16(*(const __m128i *)shortM128_128, r3);
|
||||
r4 = _mm_add_epi16(*(const __m128i *)shortM128_128, r4);
|
||||
r5 = _mm_add_epi16(*(const __m128i *)shortM128_128, r5);
|
||||
r6 = _mm_add_epi16(*(const __m128i *)shortM128_128, r6);
|
||||
r7 = _mm_add_epi16(*(const __m128i *)shortM128_128, r7);
|
||||
r0 = _mm_add_epi16(*(const __m128i*)shortM128_128, r0);
|
||||
r1 = _mm_add_epi16(*(const __m128i*)shortM128_128, r1);
|
||||
r2 = _mm_add_epi16(*(const __m128i*)shortM128_128, r2);
|
||||
r3 = _mm_add_epi16(*(const __m128i*)shortM128_128, r3);
|
||||
r4 = _mm_add_epi16(*(const __m128i*)shortM128_128, r4);
|
||||
r5 = _mm_add_epi16(*(const __m128i*)shortM128_128, r5);
|
||||
r6 = _mm_add_epi16(*(const __m128i*)shortM128_128, r6);
|
||||
r7 = _mm_add_epi16(*(const __m128i*)shortM128_128, r7);
|
||||
|
||||
((__m128i *)pOutputUB)[0] = _mm_packus_epi16(r0, r1);
|
||||
((__m128i *)pOutputUB)[1] = _mm_packus_epi16(r2, r3);
|
||||
((__m128i *)pOutputUB)[2] = _mm_packus_epi16(r4, r5);
|
||||
((__m128i *)pOutputUB)[3] = _mm_packus_epi16(r6, r7);
|
||||
((__m128i*)pOutputUB)[0] = _mm_packus_epi16(r0, r1);
|
||||
((__m128i*)pOutputUB)[1] = _mm_packus_epi16(r2, r3);
|
||||
((__m128i*)pOutputUB)[2] = _mm_packus_epi16(r4, r5);
|
||||
((__m128i*)pOutputUB)[3] = _mm_packus_epi16(r6, r7);
|
||||
}
|
||||
|
|
|
@ -14,43 +14,42 @@
|
|||
*/
|
||||
|
||||
/* I2C registers */
|
||||
#define R51x_I2C_W_SID 0x41
|
||||
#define R51x_I2C_SADDR_3 0x42
|
||||
#define R51x_I2C_SADDR_2 0x43
|
||||
#define R51x_I2C_R_SID 0x44
|
||||
#define R51x_I2C_DATA 0x45
|
||||
#define R518_I2C_CTL 0x47 /* OV518(+) only */
|
||||
#define OVFX2_I2C_ADDR 0x00
|
||||
#define R51x_I2C_W_SID 0x41
|
||||
#define R51x_I2C_SADDR_3 0x42
|
||||
#define R51x_I2C_SADDR_2 0x43
|
||||
#define R51x_I2C_R_SID 0x44
|
||||
#define R51x_I2C_DATA 0x45
|
||||
#define R518_I2C_CTL 0x47 /* OV518(+) only */
|
||||
#define OVFX2_I2C_ADDR 0x00
|
||||
|
||||
/* OV519 Camera interface register numbers */
|
||||
#define OV519_R10_H_SIZE 0x10
|
||||
#define OV519_R11_V_SIZE 0x11
|
||||
#define OV519_R12_X_OFFSETL 0x12
|
||||
#define OV519_R13_X_OFFSETH 0x13
|
||||
#define OV519_R14_Y_OFFSETL 0x14
|
||||
#define OV519_R15_Y_OFFSETH 0x15
|
||||
#define OV519_R16_DIVIDER 0x16
|
||||
#define OV519_R20_DFR 0x20
|
||||
#define OV519_R25_FORMAT 0x25
|
||||
#define OV519_R10_H_SIZE 0x10
|
||||
#define OV519_R11_V_SIZE 0x11
|
||||
#define OV519_R12_X_OFFSETL 0x12
|
||||
#define OV519_R13_X_OFFSETH 0x13
|
||||
#define OV519_R14_Y_OFFSETL 0x14
|
||||
#define OV519_R15_Y_OFFSETH 0x15
|
||||
#define OV519_R16_DIVIDER 0x16
|
||||
#define OV519_R20_DFR 0x20
|
||||
#define OV519_R25_FORMAT 0x25
|
||||
|
||||
/* OV519 System Controller register numbers */
|
||||
#define OV519_R51_RESET1 0x51
|
||||
#define OV519_R54_EN_CLK1 0x54
|
||||
#define OV519_R57_SNAPSHOT 0x57
|
||||
#define OV519_R51_RESET1 0x51
|
||||
#define OV519_R54_EN_CLK1 0x54
|
||||
#define OV519_R57_SNAPSHOT 0x57
|
||||
|
||||
#define OV519_GPIO_DATA_OUT0 0x71
|
||||
#define OV519_GPIO_IO_CTRL0 0x72
|
||||
#define OV519_GPIO_DATA_OUT0 0x71
|
||||
#define OV519_GPIO_IO_CTRL0 0x72
|
||||
|
||||
/* OV7610 registers */
|
||||
#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
|
||||
#define OV7610_REG_BLUE 0x01 /* blue channel balance */
|
||||
#define OV7610_REG_RED 0x02 /* red channel balance */
|
||||
#define OV7610_REG_SAT 0x03 /* saturation */
|
||||
#define OV8610_REG_HUE 0x04 /* 04 reserved */
|
||||
#define OV7610_REG_CNT 0x05 /* Y contrast */
|
||||
#define OV7610_REG_BRT 0x06 /* Y brightness */
|
||||
#define OV7610_REG_COM_C 0x14 /* misc common regs */
|
||||
#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 */
|
||||
|
||||
#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
|
||||
#define OV7610_REG_BLUE 0x01 /* blue channel balance */
|
||||
#define OV7610_REG_RED 0x02 /* red channel balance */
|
||||
#define OV7610_REG_SAT 0x03 /* saturation */
|
||||
#define OV8610_REG_HUE 0x04 /* 04 reserved */
|
||||
#define OV7610_REG_CNT 0x05 /* Y contrast */
|
||||
#define OV7610_REG_BRT 0x06 /* Y brightness */
|
||||
#define OV7610_REG_COM_C 0x14 /* misc common regs */
|
||||
#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 */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,36 +23,37 @@
|
|||
#include <mutex>
|
||||
|
||||
|
||||
namespace usb_eyetoy {
|
||||
|
||||
class EyeToyWebCamDevice
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
public:
|
||||
virtual ~EyeToyWebCamDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("EyeToy");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "eyetoy";
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return RegisterVideoDevice::instance().Names();
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
auto proxy = RegisterVideoDevice::instance().Proxy(name);
|
||||
if (proxy)
|
||||
return proxy->Name();
|
||||
return nullptr;
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
|
||||
} //namespace
|
||||
class EyeToyWebCamDevice
|
||||
{
|
||||
public:
|
||||
virtual ~EyeToyWebCamDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("EyeToy");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "eyetoy";
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return RegisterVideoDevice::instance().Names();
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
auto proxy = RegisterVideoDevice::instance().Proxy(name);
|
||||
if (proxy)
|
||||
return proxy->Name();
|
||||
return nullptr;
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
} // namespace usb_eyetoy
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,23 +18,24 @@
|
|||
#include "../qemu-usb/vl.h"
|
||||
#include "../configuration.h"
|
||||
|
||||
namespace usb_eyetoy {
|
||||
|
||||
class VideoDevice
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
public:
|
||||
virtual ~VideoDevice() {}
|
||||
virtual int Open() = 0;
|
||||
virtual int Close() = 0;
|
||||
virtual int GetImage(uint8_t *buf, int len) = 0;
|
||||
virtual int Reset() = 0;
|
||||
|
||||
virtual int Port() { return mPort; }
|
||||
virtual void Port(int port) { mPort = port; }
|
||||
class VideoDevice
|
||||
{
|
||||
public:
|
||||
virtual ~VideoDevice() {}
|
||||
virtual int Open() = 0;
|
||||
virtual int Close() = 0;
|
||||
virtual int GetImage(uint8_t* buf, int len) = 0;
|
||||
virtual int Reset() = 0;
|
||||
|
||||
protected:
|
||||
int mPort;
|
||||
};
|
||||
virtual int Port() { return mPort; }
|
||||
virtual void Port(int port) { mPort = port; }
|
||||
|
||||
} //namespace
|
||||
protected:
|
||||
int mPort;
|
||||
};
|
||||
|
||||
} // namespace usb_eyetoy
|
||||
#endif
|
||||
|
|
|
@ -24,60 +24,67 @@
|
|||
#include "../helpers.h"
|
||||
#include "../deviceproxy.h"
|
||||
|
||||
namespace usb_eyetoy {
|
||||
|
||||
class VideoDeviceError : public std::runtime_error
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
public:
|
||||
VideoDeviceError(const char* msg) : std::runtime_error(msg) {}
|
||||
virtual ~VideoDeviceError() throw () {}
|
||||
};
|
||||
|
||||
class VideoDeviceProxyBase : public ProxyBase
|
||||
{
|
||||
VideoDeviceProxyBase(const VideoDeviceProxyBase&) = delete;
|
||||
|
||||
public:
|
||||
VideoDeviceProxyBase() {}
|
||||
VideoDeviceProxyBase(const std::string& name);
|
||||
virtual VideoDevice* CreateObject(int port) const = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class VideoDeviceProxy : public VideoDeviceProxyBase
|
||||
{
|
||||
VideoDeviceProxy(const VideoDeviceProxy&) = delete;
|
||||
|
||||
public:
|
||||
VideoDeviceProxy() {}
|
||||
VideoDeviceProxy(const std::string& name): VideoDeviceProxyBase(name) {}
|
||||
VideoDevice* CreateObject(int port) const
|
||||
class VideoDeviceError : public std::runtime_error
|
||||
{
|
||||
try
|
||||
public:
|
||||
VideoDeviceError(const char* msg)
|
||||
: std::runtime_error(msg)
|
||||
{
|
||||
return new T(port);
|
||||
}
|
||||
catch(VideoDeviceError& err)
|
||||
{
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char *dev_type, void *data)
|
||||
{
|
||||
return T::Configure(port, dev_type, data);
|
||||
}
|
||||
};
|
||||
virtual ~VideoDeviceError() throw() {}
|
||||
};
|
||||
|
||||
class VideoDeviceProxyBase : public ProxyBase
|
||||
{
|
||||
VideoDeviceProxyBase(const VideoDeviceProxyBase&) = delete;
|
||||
|
||||
class RegisterVideoDevice : public RegisterProxy<VideoDeviceProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
VideoDeviceProxyBase() {}
|
||||
VideoDeviceProxyBase(const std::string& name);
|
||||
virtual VideoDevice* CreateObject(int port) const = 0;
|
||||
};
|
||||
|
||||
} //namespace
|
||||
template <class T>
|
||||
class VideoDeviceProxy : public VideoDeviceProxyBase
|
||||
{
|
||||
VideoDeviceProxy(const VideoDeviceProxy&) = delete;
|
||||
|
||||
public:
|
||||
VideoDeviceProxy() {}
|
||||
VideoDeviceProxy(const std::string& name)
|
||||
: VideoDeviceProxyBase(name)
|
||||
{
|
||||
}
|
||||
VideoDevice* CreateObject(int port) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return new T(port);
|
||||
}
|
||||
catch (VideoDeviceError& err)
|
||||
{
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
return T::Configure(port, dev_type, data);
|
||||
}
|
||||
};
|
||||
|
||||
class RegisterVideoDevice : public RegisterProxy<VideoDeviceProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
|
||||
} // namespace usb_eyetoy
|
||||
#endif
|
||||
|
|
|
@ -21,169 +21,178 @@
|
|||
#include <cstdio>
|
||||
#include <sstream>
|
||||
|
||||
GtkWidget *new_combobox(const char* label, GtkWidget *vbox); // src/linux/config-gtk.cpp
|
||||
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 {
|
||||
int port;
|
||||
devs_t devs;
|
||||
devs_t::const_iterator iter;
|
||||
};
|
||||
|
||||
static void PopulateHIDs(ConfigData &cfg, HIDType hid_type)
|
||||
{
|
||||
std::stringstream str;
|
||||
struct dirent* dp;
|
||||
const char* devstr[] = {"event-kbd", "event-mouse"};
|
||||
|
||||
cfg.devs.clear();
|
||||
cfg.devs.push_back(std::make_pair("None", ""));
|
||||
|
||||
DIR* dirp = opendir(EVDEV_DIR);
|
||||
if(dirp == NULL) {
|
||||
fprintf(stderr, "Error opening " EVDEV_DIR ": %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop over dir entries using readdir
|
||||
int len = strlen(devstr[hid_type]);
|
||||
while((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
// Only select names that end in 'event-joystick'
|
||||
int devlen = strlen(dp->d_name);
|
||||
if(devlen >= len)
|
||||
typedef std::vector<std::pair<std::string, std::string>> devs_t;
|
||||
struct ConfigData
|
||||
{
|
||||
const char* const start = dp->d_name + devlen - len;
|
||||
if(strncmp(start, devstr[hid_type], len) == 0) {
|
||||
OSDebugOut("%s%s\n", EVDEV_DIR, dp->d_name);
|
||||
int port;
|
||||
devs_t devs;
|
||||
devs_t::const_iterator iter;
|
||||
};
|
||||
|
||||
str.clear(); str.str("");
|
||||
str << EVDEV_DIR << dp->d_name;
|
||||
static void PopulateHIDs(ConfigData& cfg, HIDType hid_type)
|
||||
{
|
||||
std::stringstream str;
|
||||
struct dirent* dp;
|
||||
const char* devstr[] = {"event-kbd", "event-mouse"};
|
||||
|
||||
char name[1024];
|
||||
std::string dev_path = str.str();
|
||||
if (!GetEvdevName(dev_path, name))
|
||||
cfg.devs.clear();
|
||||
cfg.devs.push_back(std::make_pair("None", ""));
|
||||
|
||||
DIR* dirp = opendir(EVDEV_DIR);
|
||||
if (dirp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error opening " EVDEV_DIR ": %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop over dir entries using readdir
|
||||
int len = strlen(devstr[hid_type]);
|
||||
while ((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
// Only select names that end in 'event-joystick'
|
||||
int devlen = strlen(dp->d_name);
|
||||
if (devlen >= len)
|
||||
{
|
||||
OSDebugOut("Failed to get name: %s\n", dev_path.c_str());
|
||||
//XXX though it also could mean that controller is unusable
|
||||
cfg.devs.push_back(std::make_pair(dp->d_name, dev_path));
|
||||
}
|
||||
else
|
||||
{
|
||||
OSDebugOut("Name: %s\n", name);
|
||||
cfg.devs.push_back(std::make_pair(std::string(name), dev_path));
|
||||
const char* const start = dp->d_name + devlen - len;
|
||||
if (strncmp(start, devstr[hid_type], len) == 0)
|
||||
{
|
||||
OSDebugOut("%s%s\n", EVDEV_DIR, dp->d_name);
|
||||
|
||||
str.clear();
|
||||
str.str("");
|
||||
str << EVDEV_DIR << dp->d_name;
|
||||
|
||||
char name[1024];
|
||||
std::string dev_path = str.str();
|
||||
if (!GetEvdevName(dev_path, name))
|
||||
{
|
||||
OSDebugOut("Failed to get name: %s\n", dev_path.c_str());
|
||||
//XXX though it also could mean that controller is unusable
|
||||
cfg.devs.push_back(std::make_pair(dp->d_name, dev_path));
|
||||
}
|
||||
else
|
||||
{
|
||||
OSDebugOut("Name: %s\n", name);
|
||||
cfg.devs.push_back(std::make_pair(std::string(name), dev_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
static void combo_changed (GtkComboBox *widget, gpointer data)
|
||||
{
|
||||
gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
ConfigData *cfg = reinterpret_cast<ConfigData *> (data);
|
||||
|
||||
if (!cfg)
|
||||
return;
|
||||
|
||||
std::string &name = (cfg->devs.begin() + idx)->first;
|
||||
cfg->iter = (cfg->devs.begin() + idx);
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
}
|
||||
OSDebugOut("Selected player %d idx: %d dev: '%s'\n", 2 - cfg->port, idx, name.c_str());
|
||||
}
|
||||
|
||||
int GtkHidConfigure(int port, const char* dev_type, HIDType hid_type, GtkWindow *parent)
|
||||
{
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label, *rs_cb;
|
||||
GtkWidget *main_hbox, *right_vbox, *left_vbox;
|
||||
|
||||
assert( (int)HIDTYPE_MOUSE == 1); //make sure there is atleast two types so we won't go beyond array length
|
||||
|
||||
ConfigData cfg;
|
||||
cfg.port = port;
|
||||
|
||||
PopulateHIDs(cfg, hid_type);
|
||||
cfg.iter = cfg.devs.end();
|
||||
|
||||
std::string path;
|
||||
LoadSetting(dev_type, port, APINAME, N_DEVICE, path);
|
||||
|
||||
// ---------------------------
|
||||
GtkWidget *dlg = gtk_dialog_new_with_buttons (
|
||||
"HID Evdev Settings", parent, GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW(dlg), 320, 240);
|
||||
|
||||
// ---------------------------
|
||||
GtkWidget *dlg_area_box = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
|
||||
|
||||
main_hbox = gtk_hbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER(dlg_area_box), main_hbox);
|
||||
|
||||
// left_vbox = gtk_vbox_new (FALSE, 5);
|
||||
// gtk_box_pack_start (GTK_BOX (main_hbox), left_vbox, TRUE, TRUE, 5);
|
||||
right_vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_box_pack_start (GTK_BOX (main_hbox), right_vbox, TRUE, TRUE, 5);
|
||||
|
||||
// ---------------------------
|
||||
rs_cb = new_combobox ("Device:", right_vbox);
|
||||
|
||||
const int evdev_dir_len = strlen(EVDEV_DIR);
|
||||
int idx = 0, sel_idx = 0;
|
||||
for (auto& it : cfg.devs)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << it.first;
|
||||
if (!it.second.empty())
|
||||
str << " [" << it.second.substr(evdev_dir_len) << "]";
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rs_cb), str.str().c_str());
|
||||
if (!path.empty() && it.second == path)
|
||||
static void combo_changed(GtkComboBox* widget, gpointer data)
|
||||
{
|
||||
sel_idx = idx;
|
||||
gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
|
||||
ConfigData* cfg = reinterpret_cast<ConfigData*>(data);
|
||||
|
||||
if (!cfg)
|
||||
return;
|
||||
|
||||
std::string& name = (cfg->devs.begin() + idx)->first;
|
||||
cfg->iter = (cfg->devs.begin() + idx);
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
}
|
||||
OSDebugOut("Selected player %d idx: %d dev: '%s'\n", 2 - cfg->port, idx, name.c_str());
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
//g_object_set_data (G_OBJECT (rs_cb), CFG, &cfg);
|
||||
g_signal_connect (G_OBJECT (rs_cb), "changed", G_CALLBACK (combo_changed), reinterpret_cast<gpointer> (&cfg));
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), sel_idx);
|
||||
int GtkHidConfigure(int port, const char* dev_type, HIDType hid_type, GtkWindow* parent)
|
||||
{
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label, *rs_cb;
|
||||
GtkWidget *main_hbox, *right_vbox, *left_vbox;
|
||||
|
||||
// ---------------------------
|
||||
gtk_widget_show_all (dlg);
|
||||
gint result = gtk_dialog_run (GTK_DIALOG (dlg));
|
||||
assert((int)HIDTYPE_MOUSE == 1); //make sure there is atleast two types so we won't go beyond array length
|
||||
|
||||
int ret = RESULT_OK;
|
||||
if (result == GTK_RESPONSE_OK)
|
||||
{
|
||||
if (cfg.iter != cfg.devs.end()) {
|
||||
if (!SaveSetting(dev_type, port, APINAME, N_DEVICE, cfg.iter->second))
|
||||
ret = RESULT_FAILED;
|
||||
ConfigData cfg;
|
||||
cfg.port = port;
|
||||
|
||||
PopulateHIDs(cfg, hid_type);
|
||||
cfg.iter = cfg.devs.end();
|
||||
|
||||
std::string path;
|
||||
LoadSetting(dev_type, port, APINAME, N_DEVICE, path);
|
||||
|
||||
// ---------------------------
|
||||
GtkWidget* dlg = gtk_dialog_new_with_buttons(
|
||||
"HID Evdev Settings", parent, GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dlg), 320, 240);
|
||||
|
||||
// ---------------------------
|
||||
GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
|
||||
|
||||
main_hbox = gtk_hbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg_area_box), main_hbox);
|
||||
|
||||
// left_vbox = gtk_vbox_new (FALSE, 5);
|
||||
// gtk_box_pack_start (GTK_BOX (main_hbox), left_vbox, TRUE, TRUE, 5);
|
||||
right_vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 5);
|
||||
|
||||
// ---------------------------
|
||||
rs_cb = new_combobox("Device:", right_vbox);
|
||||
|
||||
const int evdev_dir_len = strlen(EVDEV_DIR);
|
||||
int idx = 0, sel_idx = 0;
|
||||
for (auto& it : cfg.devs)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << it.first;
|
||||
if (!it.second.empty())
|
||||
str << " [" << it.second.substr(evdev_dir_len) << "]";
|
||||
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), str.str().c_str());
|
||||
if (!path.empty() && it.second == path)
|
||||
{
|
||||
sel_idx = idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
//g_object_set_data (G_OBJECT (rs_cb), CFG, &cfg);
|
||||
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(combo_changed), reinterpret_cast<gpointer>(&cfg));
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), sel_idx);
|
||||
|
||||
// ---------------------------
|
||||
gtk_widget_show_all(dlg);
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
|
||||
int ret = RESULT_OK;
|
||||
if (result == GTK_RESPONSE_OK)
|
||||
{
|
||||
if (cfg.iter != cfg.devs.end())
|
||||
{
|
||||
if (!SaveSetting(dev_type, port, APINAME, N_DEVICE, cfg.iter->second))
|
||||
ret = RESULT_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = RESULT_CANCELED;
|
||||
|
||||
gtk_widget_destroy(dlg);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = RESULT_CANCELED;
|
||||
|
||||
gtk_widget_destroy (dlg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EvDev::Configure(int port, const char* dev_type, HIDType hid_type, void *data)
|
||||
{
|
||||
return GtkHidConfigure(port, dev_type, hid_type, GTK_WINDOW (data));
|
||||
}
|
||||
int EvDev::Configure(int port, const char* dev_type, HIDType hid_type, void* data)
|
||||
{
|
||||
return GtkHidConfigure(port, dev_type, hid_type, GTK_WINDOW(data));
|
||||
}
|
||||
|
||||
#undef EVDEV_DIR
|
||||
}} //namespace
|
||||
} // namespace evdev
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -23,125 +23,133 @@
|
|||
#ifdef USING_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
extern Display *g_GSdsp;
|
||||
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)
|
||||
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
|
||||
#define NBITS(x) ((((x)-1) / (sizeof(long) * 8)) + 1)
|
||||
|
||||
bool FindHid(const std::string &evphys, std::string& hid_dev)
|
||||
{
|
||||
int fd;
|
||||
int res;
|
||||
char buf[256];
|
||||
bool FindHid(const std::string& evphys, std::string& hid_dev)
|
||||
{
|
||||
int fd;
|
||||
int res;
|
||||
char buf[256];
|
||||
|
||||
std::stringstream str;
|
||||
struct dirent* dp;
|
||||
std::stringstream str;
|
||||
struct dirent* dp;
|
||||
|
||||
DIR* dirp = opendir("/dev/input/");
|
||||
if(dirp == NULL) {
|
||||
perror("Error opening /dev/input/");
|
||||
return false;
|
||||
}
|
||||
|
||||
while((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(strncmp(dp->d_name, "hidraw", 6) == 0) {
|
||||
OSDebugOut("%s\n", dp->d_name);
|
||||
|
||||
str.clear(); str.str("");
|
||||
str << "/dev/input/" << dp->d_name;
|
||||
fd = open(str.str().c_str(), O_RDWR|O_NONBLOCK);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("Unable to open device");
|
||||
continue;
|
||||
DIR* dirp = opendir("/dev/input/");
|
||||
if (dirp == NULL)
|
||||
{
|
||||
perror("Error opening /dev/input/");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(buf, 0x0, sizeof(buf));
|
||||
//res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
|
||||
while ((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (strncmp(dp->d_name, "hidraw", 6) == 0)
|
||||
{
|
||||
OSDebugOut("%s\n", dp->d_name);
|
||||
|
||||
/* res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
|
||||
str.clear();
|
||||
str.str("");
|
||||
str << "/dev/input/" << dp->d_name;
|
||||
fd = open(str.str().c_str(), O_RDWR | O_NONBLOCK);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
perror("Unable to open device");
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(buf, 0x0, sizeof(buf));
|
||||
//res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
|
||||
|
||||
/* res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
|
||||
if (res < 0)
|
||||
perror("HIDIOCGRAWPHYS");
|
||||
else
|
||||
OSDebugOut("Raw Phys: %s\n", buf);*/
|
||||
close(fd);
|
||||
if (evphys == buf) {
|
||||
closedir(dirp);
|
||||
hid_dev = str.str();
|
||||
return true;
|
||||
close(fd);
|
||||
if (evphys == buf)
|
||||
{
|
||||
closedir(dirp);
|
||||
hid_dev = str.str();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
quit:
|
||||
closedir(dirp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
quit:
|
||||
closedir(dirp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int EvDev::TokenOut(const uint8_t *data, int len)
|
||||
{
|
||||
return len;
|
||||
}
|
||||
int EvDev::TokenOut(const uint8_t* data, int len)
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
int EvDev::Open()
|
||||
{
|
||||
// Make sure there is atleast two types so we won't go beyond array length
|
||||
assert( (int)HIDTYPE_MOUSE == 1 );
|
||||
int t;
|
||||
std::stringstream name;
|
||||
char buf[1024];
|
||||
int EvDev::Open()
|
||||
{
|
||||
// Make sure there is atleast two types so we won't go beyond array length
|
||||
assert((int)HIDTYPE_MOUSE == 1);
|
||||
int t;
|
||||
std::stringstream name;
|
||||
char buf[1024];
|
||||
|
||||
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
|
||||
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
||||
unsigned long keybit[NBITS(KEY_MAX)] = {0};
|
||||
unsigned long absbit[NBITS(ABS_MAX)] = {0};
|
||||
|
||||
memset(mAxisMap, -1, sizeof(mAxisMap));
|
||||
memset(mBtnMap, -1, sizeof(mBtnMap));
|
||||
memset(mAxisMap, -1, sizeof(mAxisMap));
|
||||
memset(mBtnMap, -1, sizeof(mBtnMap));
|
||||
|
||||
mAxisCount = 0;
|
||||
mButtonCount = 0;
|
||||
mHandle = -1;
|
||||
mAxisCount = 0;
|
||||
mButtonCount = 0;
|
||||
mHandle = -1;
|
||||
|
||||
std::string path;
|
||||
if (!LoadSetting(mDevType, mPort, APINAME, N_DEVICE, path))
|
||||
{
|
||||
OSDebugOut("Cannot load evdev hid device setting!\n");
|
||||
return 1;
|
||||
}
|
||||
std::string path;
|
||||
if (!LoadSetting(mDevType, mPort, APINAME, N_DEVICE, path))
|
||||
{
|
||||
OSDebugOut("Cannot load evdev hid device setting!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(path.empty() || !file_exists(path))
|
||||
goto quit;
|
||||
if (path.empty() || !file_exists(path))
|
||||
goto quit;
|
||||
|
||||
/*if (GetEvdevName(joypath, buf)) {
|
||||
/*if (GetEvdevName(joypath, buf)) {
|
||||
name << buf;
|
||||
name << " (evdev)";
|
||||
}*/
|
||||
|
||||
if ((mHandle = open(path.c_str(), O_RDWR | O_NONBLOCK)) < 0)
|
||||
{
|
||||
OSDebugOut("Cannot open device: %s\n", path.c_str());
|
||||
goto quit;
|
||||
}
|
||||
if ((mHandle = open(path.c_str(), O_RDWR | O_NONBLOCK)) < 0)
|
||||
{
|
||||
OSDebugOut("Cannot open device: %s\n", path.c_str());
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* if ((ioctl(mHandle, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) &&
|
||||
/* if ((ioctl(mHandle, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) &&
|
||||
(ioctl(mHandle, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0)) {
|
||||
// Probably isn't a evdev joystick
|
||||
SysMessage(APINAME ": Getting atleast some of the bits failed: %s\n", strerror(errno));
|
||||
goto quit;
|
||||
}*/
|
||||
|
||||
/*unsigned int version;
|
||||
/*unsigned int version;
|
||||
if (ioctl(mHandle, EVIOCGVERSION, &version) < 0)
|
||||
{
|
||||
SysMessage(APINAME ": Get version failed: %s\n", strerror(errno));
|
||||
return false;
|
||||
}*/
|
||||
|
||||
/* for (int i = 0; i < KEY_MAX; ++i) {
|
||||
/* for (int i = 0; i < KEY_MAX; ++i) {
|
||||
if (test_bit(i, keybit)) {
|
||||
OSDebugOut("Joystick has button: 0x%x\n", i);
|
||||
mBtnMap[i] = mButtonCount;
|
||||
|
@ -149,194 +157,203 @@ int EvDev::Open()
|
|||
}
|
||||
}*/
|
||||
|
||||
if (!mReaderThreadIsRunning)
|
||||
{
|
||||
if (mReaderThread.joinable())
|
||||
mReaderThread.join();
|
||||
mReaderThread = std::thread(EvDev::ReaderThread, this);
|
||||
}
|
||||
return 0;
|
||||
|
||||
quit:
|
||||
Close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EvDev::Close()
|
||||
{
|
||||
if (mHandle != -1)
|
||||
close(mHandle);
|
||||
|
||||
mHandle = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EvDev::ReaderThread(void *ptr)
|
||||
{
|
||||
ssize_t len;
|
||||
input_event events[32];
|
||||
|
||||
EvDev *dev = static_cast<EvDev *>(ptr);
|
||||
HIDState *hs = dev->mHIDState;
|
||||
int32_t lastX = 0, lastY = 0;
|
||||
bool shift = false;
|
||||
bool grabbed = false;
|
||||
|
||||
dev->mReaderThreadIsRunning = true;
|
||||
|
||||
while (dev->mHandle != -1)
|
||||
{
|
||||
//Non-blocking read sets len to -1 and errno to EAGAIN if no new data
|
||||
while((len = read(dev->mHandle, &events, sizeof(events))) > -1)
|
||||
{
|
||||
InputEvent ev{};
|
||||
len /= sizeof(events[0]);
|
||||
for (int i = 0; i < len; i++)
|
||||
if (!mReaderThreadIsRunning)
|
||||
{
|
||||
input_event& event = events[i];
|
||||
switch (event.type)
|
||||
{
|
||||
case EV_ABS:
|
||||
{
|
||||
OSDebugOut("EV_ABS: %d, val: %d\n", event.code, event.value);
|
||||
|
||||
if (dev->mHIDType == HIDTYPE_MOUSE) // usually mouse position is expected to be relative
|
||||
continue;
|
||||
|
||||
if (!hs->ptr.eh_entry)
|
||||
continue;
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_ABS;
|
||||
if (event.code == ABS_X)
|
||||
{
|
||||
ev.u.abs.axis = INPUT_AXIS_X;
|
||||
ev.u.abs.value = event.value;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
else if (event.code == ABS_Y)
|
||||
{
|
||||
ev.u.abs.axis = INPUT_AXIS_Y;
|
||||
ev.u.abs.value = event.value;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_REL:
|
||||
{
|
||||
OSDebugOut("EV_REL: %d, val: %d\n", event.code, event.value);
|
||||
if (!hs->ptr.eh_entry)
|
||||
continue;
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_REL;
|
||||
ev.u.rel.value = event.value;
|
||||
if (event.code == ABS_X)
|
||||
{
|
||||
ev.u.rel.axis = INPUT_AXIS_X;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
else if (event.code == ABS_Y)
|
||||
{
|
||||
ev.u.rel.axis = INPUT_AXIS_Y;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_KEY:
|
||||
{
|
||||
OSDebugOut("EV_KEY: 0x%02x (%d), val: %d\n", event.code, event.code, event.value);
|
||||
|
||||
#ifdef USING_X11 //FIXME not thread-safe
|
||||
if (event.code == KEY_LEFTSHIFT || event.code == KEY_RIGHTSHIFT)
|
||||
shift = (event.value > 0);
|
||||
|
||||
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 {
|
||||
grabbed = false;
|
||||
XUngrabPointer(g_GSdsp, CurrentTime);
|
||||
XUngrabKeyboard(g_GSdsp, CurrentTime);
|
||||
XFixesShowCursor(g_GSdsp, g_GSwin);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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) {
|
||||
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;
|
||||
ev.u.key.key.u.qcode = qcode;
|
||||
|
||||
hs->kbd.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (hs->ptr.eh_entry) {
|
||||
ev.type = INPUT_EVENT_KIND_BTN;
|
||||
switch(event.code)
|
||||
{
|
||||
case BTN_LEFT:
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_SYN: //TODO useful?
|
||||
{
|
||||
OSDebugOut("EV_SYN: %d, val: %d\n", event.code, event.value);
|
||||
switch(event.code) {
|
||||
case SYN_REPORT:
|
||||
if (hs->ptr.eh_sync) //TODO sync here?
|
||||
hs->ptr.eh_sync(hs);
|
||||
break;
|
||||
case SYN_DROPPED:
|
||||
//restore last good state
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (mReaderThread.joinable())
|
||||
mReaderThread.join();
|
||||
mReaderThread = std::thread(EvDev::ReaderThread, this);
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (len < sizeof(input_event) && errno != EAGAIN)
|
||||
{
|
||||
OSDebugOut("%s: evdev read error %d\n", APINAME, errno);
|
||||
break;
|
||||
}
|
||||
quit:
|
||||
Close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
OSDebugOut(TEXT("ReaderThread exited.\n"));
|
||||
int EvDev::Close()
|
||||
{
|
||||
if (mHandle != -1)
|
||||
close(mHandle);
|
||||
|
||||
dev->mReaderThreadIsRunning = false;
|
||||
}
|
||||
mHandle = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}} //namespace
|
||||
void EvDev::ReaderThread(void* ptr)
|
||||
{
|
||||
ssize_t len;
|
||||
input_event events[32];
|
||||
|
||||
EvDev* dev = static_cast<EvDev*>(ptr);
|
||||
HIDState* hs = dev->mHIDState;
|
||||
int32_t lastX = 0, lastY = 0;
|
||||
bool shift = false;
|
||||
bool grabbed = false;
|
||||
|
||||
dev->mReaderThreadIsRunning = true;
|
||||
|
||||
while (dev->mHandle != -1)
|
||||
{
|
||||
//Non-blocking read sets len to -1 and errno to EAGAIN if no new data
|
||||
while ((len = read(dev->mHandle, &events, sizeof(events))) > -1)
|
||||
{
|
||||
InputEvent ev{};
|
||||
len /= sizeof(events[0]);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
input_event& event = events[i];
|
||||
switch (event.type)
|
||||
{
|
||||
case EV_ABS:
|
||||
{
|
||||
OSDebugOut("EV_ABS: %d, val: %d\n", event.code, event.value);
|
||||
|
||||
if (dev->mHIDType == HIDTYPE_MOUSE) // usually mouse position is expected to be relative
|
||||
continue;
|
||||
|
||||
if (!hs->ptr.eh_entry)
|
||||
continue;
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_ABS;
|
||||
if (event.code == ABS_X)
|
||||
{
|
||||
ev.u.abs.axis = INPUT_AXIS_X;
|
||||
ev.u.abs.value = event.value;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
else if (event.code == ABS_Y)
|
||||
{
|
||||
ev.u.abs.axis = INPUT_AXIS_Y;
|
||||
ev.u.abs.value = event.value;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_REL:
|
||||
{
|
||||
OSDebugOut("EV_REL: %d, val: %d\n", event.code, event.value);
|
||||
if (!hs->ptr.eh_entry)
|
||||
continue;
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_REL;
|
||||
ev.u.rel.value = event.value;
|
||||
if (event.code == ABS_X)
|
||||
{
|
||||
ev.u.rel.axis = INPUT_AXIS_X;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
else if (event.code == ABS_Y)
|
||||
{
|
||||
ev.u.rel.axis = INPUT_AXIS_Y;
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_KEY:
|
||||
{
|
||||
OSDebugOut("EV_KEY: 0x%02x (%d), val: %d\n", event.code, event.code, event.value);
|
||||
|
||||
#ifdef USING_X11 //FIXME not thread-safe
|
||||
if (event.code == KEY_LEFTSHIFT || event.code == KEY_RIGHTSHIFT)
|
||||
shift = (event.value > 0);
|
||||
|
||||
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
|
||||
{
|
||||
grabbed = false;
|
||||
XUngrabPointer(g_GSdsp, CurrentTime);
|
||||
XUngrabKeyboard(g_GSdsp, CurrentTime);
|
||||
XFixesShowCursor(g_GSdsp, g_GSwin);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
ev.u.key.key.u.qcode = qcode;
|
||||
|
||||
hs->kbd.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (hs->ptr.eh_entry)
|
||||
{
|
||||
ev.type = INPUT_EVENT_KIND_BTN;
|
||||
switch (event.code)
|
||||
{
|
||||
case BTN_LEFT:
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = (event.value == 1);
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EV_SYN: //TODO useful?
|
||||
{
|
||||
OSDebugOut("EV_SYN: %d, val: %d\n", event.code, event.value);
|
||||
switch (event.code)
|
||||
{
|
||||
case SYN_REPORT:
|
||||
if (hs->ptr.eh_sync) //TODO sync here?
|
||||
hs->ptr.eh_sync(hs);
|
||||
break;
|
||||
case SYN_DROPPED:
|
||||
//restore last good state
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < sizeof(input_event) && errno != EAGAIN)
|
||||
{
|
||||
OSDebugOut("%s: evdev read error %d\n", APINAME, errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
OSDebugOut(TEXT("ReaderThread exited.\n"));
|
||||
|
||||
dev->mReaderThreadIsRunning = false;
|
||||
}
|
||||
|
||||
} // namespace evdev
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -22,65 +22,71 @@
|
|||
#include <atomic>
|
||||
#include "../usb-hid.h"
|
||||
|
||||
namespace usb_hid { namespace evdev {
|
||||
|
||||
static const char *APINAME = "evdev";
|
||||
|
||||
class EvDev : public UsbHID
|
||||
namespace usb_hid
|
||||
{
|
||||
public:
|
||||
EvDev(int port, const char* dev_type): UsbHID(port, dev_type)
|
||||
, mHandle(-1)
|
||||
, mReaderThreadIsRunning(false)
|
||||
namespace evdev
|
||||
{
|
||||
}
|
||||
|
||||
~EvDev() { Close(); }
|
||||
int Open();
|
||||
int Close();
|
||||
int TokenIn(uint8_t *buf, int len);
|
||||
int TokenOut(const uint8_t *data, int len);
|
||||
int Reset() { return 0; }
|
||||
static const char* APINAME = "evdev";
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Evdev");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType hid_type, void *data);
|
||||
protected:
|
||||
static void ReaderThread(void *ptr);
|
||||
|
||||
int mHandle;
|
||||
uint16_t mAxisMap[ABS_MAX + 1];
|
||||
uint16_t mBtnMap[KEY_MAX + 1];
|
||||
int mAxisCount;
|
||||
int mButtonCount;
|
||||
|
||||
std::thread mReaderThread;
|
||||
std::atomic<bool> mReaderThreadIsRunning;
|
||||
};
|
||||
|
||||
template< size_t _Size >
|
||||
bool GetEvdevName(const std::string& path, char (&name)[_Size])
|
||||
{
|
||||
int fd = 0;
|
||||
if ((fd = open(path.c_str(), O_RDONLY)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot open %s\n", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ioctl(fd, EVIOCGNAME(_Size), name) < -1)
|
||||
class EvDev : public UsbHID
|
||||
{
|
||||
fprintf(stderr, "Cannot get controller's name\n");
|
||||
close(fd);
|
||||
public:
|
||||
EvDev(int port, const char* dev_type)
|
||||
: UsbHID(port, dev_type)
|
||||
, mHandle(-1)
|
||||
, mReaderThreadIsRunning(false)
|
||||
{
|
||||
}
|
||||
|
||||
~EvDev() { Close(); }
|
||||
int Open();
|
||||
int Close();
|
||||
int TokenIn(uint8_t* buf, int len);
|
||||
int TokenOut(const uint8_t* data, int len);
|
||||
int Reset() { return 0; }
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Evdev");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType hid_type, void* data);
|
||||
|
||||
protected:
|
||||
static void ReaderThread(void* ptr);
|
||||
|
||||
int mHandle;
|
||||
uint16_t mAxisMap[ABS_MAX + 1];
|
||||
uint16_t mBtnMap[KEY_MAX + 1];
|
||||
int mAxisCount;
|
||||
int mButtonCount;
|
||||
|
||||
std::thread mReaderThread;
|
||||
std::atomic<bool> mReaderThreadIsRunning;
|
||||
};
|
||||
|
||||
template <size_t _Size>
|
||||
bool GetEvdevName(const std::string& path, char (&name)[_Size])
|
||||
{
|
||||
int fd = 0;
|
||||
if ((fd = open(path.c_str(), O_RDONLY)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot open %s\n", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ioctl(fd, EVIOCGNAME(_Size), name) < -1)
|
||||
{
|
||||
fprintf(stderr, "Cannot get controller's name\n");
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}} //namespace
|
||||
} // namespace evdev
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -24,66 +24,73 @@
|
|||
#include "../helpers.h"
|
||||
#include "../deviceproxy.h"
|
||||
|
||||
namespace usb_hid {
|
||||
|
||||
class UsbHIDError : public std::runtime_error
|
||||
namespace usb_hid
|
||||
{
|
||||
public:
|
||||
UsbHIDError(const char* msg) : std::runtime_error(msg) {}
|
||||
virtual ~UsbHIDError() throw () {}
|
||||
};
|
||||
|
||||
class UsbHIDProxyBase : public ProxyBase
|
||||
{
|
||||
UsbHIDProxyBase(const UsbHIDProxyBase&) = delete;
|
||||
|
||||
public:
|
||||
UsbHIDProxyBase() {}
|
||||
UsbHIDProxyBase(const std::string& name);
|
||||
virtual UsbHID* CreateObject(int port, const char* dev_type) const = 0;
|
||||
// ProxyBase::Configure is ignored
|
||||
virtual int Configure(int port, const char* dev_type, HIDType hid_type, void *data) = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class UsbHIDProxy : public UsbHIDProxyBase
|
||||
{
|
||||
UsbHIDProxy(const UsbHIDProxy&) = delete;
|
||||
|
||||
public:
|
||||
UsbHIDProxy() {}
|
||||
UsbHIDProxy(const std::string& name): UsbHIDProxyBase(name) {}
|
||||
UsbHID* CreateObject(int port, const char* dev_type) const
|
||||
class UsbHIDError : public std::runtime_error
|
||||
{
|
||||
try
|
||||
public:
|
||||
UsbHIDError(const char* msg)
|
||||
: std::runtime_error(msg)
|
||||
{
|
||||
return new T(port, dev_type);
|
||||
}
|
||||
catch(UsbHIDError& err)
|
||||
{
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, void *data)
|
||||
{
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, HIDType hid_type, void *data)
|
||||
{
|
||||
return T::Configure(port, dev_type, hid_type, data);
|
||||
}
|
||||
};
|
||||
virtual ~UsbHIDError() throw() {}
|
||||
};
|
||||
|
||||
class UsbHIDProxyBase : public ProxyBase
|
||||
{
|
||||
UsbHIDProxyBase(const UsbHIDProxyBase&) = delete;
|
||||
|
||||
class RegisterUsbHID : public RegisterProxy<UsbHIDProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
UsbHIDProxyBase() {}
|
||||
UsbHIDProxyBase(const std::string& name);
|
||||
virtual UsbHID* CreateObject(int port, const char* dev_type) const = 0;
|
||||
// ProxyBase::Configure is ignored
|
||||
virtual int Configure(int port, const char* dev_type, HIDType hid_type, void* data) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
template <class T>
|
||||
class UsbHIDProxy : public UsbHIDProxyBase
|
||||
{
|
||||
UsbHIDProxy(const UsbHIDProxy&) = delete;
|
||||
|
||||
public:
|
||||
UsbHIDProxy() {}
|
||||
UsbHIDProxy(const std::string& name)
|
||||
: UsbHIDProxyBase(name)
|
||||
{
|
||||
}
|
||||
UsbHID* CreateObject(int port, const char* dev_type) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return new T(port, dev_type);
|
||||
}
|
||||
catch (UsbHIDError& err)
|
||||
{
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, HIDType hid_type, void* data)
|
||||
{
|
||||
return T::Configure(port, dev_type, hid_type, data);
|
||||
}
|
||||
};
|
||||
|
||||
class RegisterUsbHID : public RegisterProxy<UsbHIDProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
|
||||
} // namespace usb_hid
|
||||
#endif
|
||||
|
|
|
@ -16,30 +16,37 @@
|
|||
#include "usb-hid.h"
|
||||
#include "hidproxy.h"
|
||||
|
||||
namespace usb_hid { namespace noop {
|
||||
|
||||
static const char *APINAME = "noop";
|
||||
|
||||
class NOOP : public UsbHID
|
||||
namespace usb_hid
|
||||
{
|
||||
public:
|
||||
NOOP(int port, const char* dev_type): UsbHID(port, dev_type) {}
|
||||
~NOOP() {}
|
||||
int Open() { return 0; }
|
||||
int Close() { return 0; }
|
||||
int TokenIn(uint8_t *buf, int len) { return len; }
|
||||
int TokenOut(const uint8_t *data, int len) { return len; }
|
||||
int Reset() { return 0; }
|
||||
|
||||
static const TCHAR* Name()
|
||||
namespace noop
|
||||
{
|
||||
return TEXT("NOOP");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType type, void *data)
|
||||
{
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
};
|
||||
static const char* APINAME = "noop";
|
||||
|
||||
}}
|
||||
class NOOP : public UsbHID
|
||||
{
|
||||
public:
|
||||
NOOP(int port, const char* dev_type)
|
||||
: UsbHID(port, dev_type)
|
||||
{
|
||||
}
|
||||
~NOOP() {}
|
||||
int Open() { return 0; }
|
||||
int Close() { return 0; }
|
||||
int TokenIn(uint8_t* buf, int len) { return len; }
|
||||
int TokenOut(const uint8_t* data, int len) { return len; }
|
||||
int Reset() { return 0; }
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("NOOP");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType type, void* data)
|
||||
{
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace noop
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -18,216 +18,234 @@
|
|||
#include "qemu-usb/input-keymap.h"
|
||||
#include "qemu-usb/input-keymap-win32-to-qcode.h"
|
||||
|
||||
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)
|
||||
|
||||
// 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)"
|
||||
// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
|
||||
|
||||
int RawInput::TokenOut(const uint8_t *data, int len)
|
||||
namespace usb_hid
|
||||
{
|
||||
// std::array<uint8_t, 8> report{ 0 };
|
||||
// memcpy(report.data() + 1, data, report.size() - 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void ParseRawInput(PRAWINPUT pRawInput, HIDState *hs)
|
||||
{
|
||||
PHIDP_PREPARSED_DATA pPreparsedData = NULL;
|
||||
HIDP_CAPS Caps;
|
||||
PHIDP_BUTTON_CAPS pButtonCaps = NULL;
|
||||
PHIDP_VALUE_CAPS pValueCaps = NULL;
|
||||
UINT bufferSize = 0;
|
||||
ULONG usageLength, value;
|
||||
TCHAR name[1024] = {0};
|
||||
UINT nameSize = 1024;
|
||||
RID_DEVICE_INFO devInfo = {0};
|
||||
std::wstring devName;
|
||||
USHORT capsLength = 0;
|
||||
USAGE usage[32] = {0};
|
||||
int numberOfButtons;
|
||||
|
||||
GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, name, &nameSize);
|
||||
|
||||
devName = name;
|
||||
std::transform(devName.begin(), devName.end(), devName.begin(), ::toupper);
|
||||
|
||||
CHECK( GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0 );
|
||||
CHECK( pPreparsedData = (PHIDP_PREPARSED_DATA)malloc(bufferSize) );
|
||||
CHECK( (int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0 );
|
||||
CHECK( HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS );
|
||||
|
||||
//Get pressed buttons
|
||||
CHECK( pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * Caps.NumberInputButtonCaps) );
|
||||
//If fails, maybe wheel only has axes
|
||||
capsLength = Caps.NumberInputButtonCaps;
|
||||
HidP_GetButtonCaps(HidP_Input, pButtonCaps, &capsLength, pPreparsedData);
|
||||
|
||||
numberOfButtons = pButtonCaps->Range.UsageMax - pButtonCaps->Range.UsageMin + 1;
|
||||
usageLength = countof(usage);//numberOfButtons;
|
||||
|
||||
NTSTATUS stat;
|
||||
if((stat = HidP_GetUsages(
|
||||
HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
|
||||
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid)) == HIDP_STATUS_SUCCESS )
|
||||
namespace raw
|
||||
{
|
||||
for(uint32_t i = 0; i < usageLength; i++)
|
||||
|
||||
#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)"
|
||||
// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
|
||||
|
||||
int RawInput::TokenOut(const uint8_t* data, int len)
|
||||
{
|
||||
uint16_t btn = usage[i] - pButtonCaps->Range.UsageMin;
|
||||
// std::array<uint8_t, 8> report{ 0 };
|
||||
// memcpy(report.data() + 1, data, report.size() - 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get axes' values
|
||||
CHECK( pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps) );
|
||||
capsLength = Caps.NumberInputValueCaps;
|
||||
if(HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )
|
||||
{
|
||||
for(USHORT i = 0; i < capsLength; i++)
|
||||
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 )
|
||||
PHIDP_PREPARSED_DATA pPreparsedData = NULL;
|
||||
HIDP_CAPS Caps;
|
||||
PHIDP_BUTTON_CAPS pButtonCaps = NULL;
|
||||
PHIDP_VALUE_CAPS pValueCaps = NULL;
|
||||
UINT bufferSize = 0;
|
||||
ULONG usageLength, value;
|
||||
TCHAR name[1024] = {0};
|
||||
UINT nameSize = 1024;
|
||||
RID_DEVICE_INFO devInfo = {0};
|
||||
std::wstring devName;
|
||||
USHORT capsLength = 0;
|
||||
USAGE usage[32] = {0};
|
||||
int numberOfButtons;
|
||||
|
||||
GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, name, &nameSize);
|
||||
|
||||
devName = name;
|
||||
std::transform(devName.begin(), devName.end(), devName.begin(), ::toupper);
|
||||
|
||||
CHECK(GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0);
|
||||
CHECK(pPreparsedData = (PHIDP_PREPARSED_DATA)malloc(bufferSize));
|
||||
CHECK((int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0);
|
||||
CHECK(HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS);
|
||||
|
||||
//Get pressed buttons
|
||||
CHECK(pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * Caps.NumberInputButtonCaps));
|
||||
//If fails, maybe wheel only has axes
|
||||
capsLength = Caps.NumberInputButtonCaps;
|
||||
HidP_GetButtonCaps(HidP_Input, pButtonCaps, &capsLength, pPreparsedData);
|
||||
|
||||
numberOfButtons = pButtonCaps->Range.UsageMax - pButtonCaps->Range.UsageMin + 1;
|
||||
usageLength = countof(usage); //numberOfButtons;
|
||||
|
||||
NTSTATUS stat;
|
||||
if ((stat = HidP_GetUsages(
|
||||
HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
|
||||
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid)) == HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
continue; // if here then maybe something is up with HIDP_CAPS.NumberInputValueCaps
|
||||
for (uint32_t i = 0; i < usageLength; i++)
|
||||
{
|
||||
uint16_t btn = usage[i] - pButtonCaps->Range.UsageMin;
|
||||
}
|
||||
}
|
||||
|
||||
switch(pValueCaps[i].Range.UsageMin)
|
||||
/// Get axes' values
|
||||
CHECK(pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps));
|
||||
capsLength = Caps.NumberInputValueCaps;
|
||||
if (HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
case HID_USAGE_GENERIC_X: //0x30
|
||||
case HID_USAGE_GENERIC_Y:
|
||||
case HID_USAGE_GENERIC_Z:
|
||||
case HID_USAGE_GENERIC_RX:
|
||||
case HID_USAGE_GENERIC_RY:
|
||||
case HID_USAGE_GENERIC_RZ: //0x35
|
||||
//int axis = (value * 0x3FFF) / pValueCaps[i].LogicalMax;
|
||||
break;
|
||||
case HID_USAGE_GENERIC_HATSWITCH:
|
||||
//fprintf(stderr, "Hat: %02X\n", value);
|
||||
break;
|
||||
for (USHORT i = 0; i < capsLength; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
continue; // if here then maybe something is up with HIDP_CAPS.NumberInputValueCaps
|
||||
}
|
||||
|
||||
switch (pValueCaps[i].Range.UsageMin)
|
||||
{
|
||||
case HID_USAGE_GENERIC_X: //0x30
|
||||
case HID_USAGE_GENERIC_Y:
|
||||
case HID_USAGE_GENERIC_Z:
|
||||
case HID_USAGE_GENERIC_RX:
|
||||
case HID_USAGE_GENERIC_RY:
|
||||
case HID_USAGE_GENERIC_RZ: //0x35
|
||||
//int axis = (value * 0x3FFF) / pValueCaps[i].LogicalMax;
|
||||
break;
|
||||
case HID_USAGE_GENERIC_HATSWITCH:
|
||||
//fprintf(stderr, "Hat: %02X\n", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Error:
|
||||
SAFE_FREE(pPreparsedData);
|
||||
SAFE_FREE(pButtonCaps);
|
||||
SAFE_FREE(pValueCaps);
|
||||
}
|
||||
|
||||
static void ParseRawInputKB(RAWKEYBOARD& k, HIDState* hs)
|
||||
{
|
||||
if (!hs->kbd.eh_entry)
|
||||
return;
|
||||
static uint32_t nr = 0;
|
||||
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 (KEYBOARD_OVERRUN_MAKE_CODE == k.MakeCode)
|
||||
return;
|
||||
|
||||
QKeyCode qcode = Q_KEY_CODE_UNMAPPED;
|
||||
if (k.VKey < (int)qemu_input_map_win32_to_qcode.size())
|
||||
qcode = qemu_input_map_win32_to_qcode[k.VKey];
|
||||
|
||||
//TODO
|
||||
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)
|
||||
qcode = Q_KEY_CODE_CTRL_R;
|
||||
else if (Q_KEY_CODE_ALT == qcode)
|
||||
qcode = Q_KEY_CODE_ALT_R;
|
||||
}
|
||||
|
||||
InputEvent ev{};
|
||||
ev.type = INPUT_EVENT_KIND_KEY;
|
||||
ev.u.key.down = !k.Flags;
|
||||
ev.u.key.key.type = KEY_VALUE_KIND_QCODE;
|
||||
ev.u.key.key.u.qcode = qcode;
|
||||
|
||||
hs->kbd.eh_entry(hs, &ev);
|
||||
}
|
||||
|
||||
static void SendPointerEvent(InputEvent& ev, HIDState* hs)
|
||||
{
|
||||
if (hs->ptr.eh_entry)
|
||||
{
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Error:
|
||||
SAFE_FREE(pPreparsedData);
|
||||
SAFE_FREE(pButtonCaps);
|
||||
SAFE_FREE(pValueCaps);
|
||||
}
|
||||
|
||||
static void ParseRawInputKB(RAWKEYBOARD &k, HIDState *hs)
|
||||
{
|
||||
if (!hs->kbd.eh_entry)
|
||||
return;
|
||||
static uint32_t nr = 0;
|
||||
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 (KEYBOARD_OVERRUN_MAKE_CODE == k.MakeCode)
|
||||
return;
|
||||
|
||||
QKeyCode qcode = Q_KEY_CODE_UNMAPPED;
|
||||
if (k.VKey < (int)qemu_input_map_win32_to_qcode.size())
|
||||
qcode = qemu_input_map_win32_to_qcode[k.VKey];
|
||||
|
||||
//TODO
|
||||
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)
|
||||
qcode = Q_KEY_CODE_CTRL_R;
|
||||
else if (Q_KEY_CODE_ALT == qcode)
|
||||
qcode = Q_KEY_CODE_ALT_R;
|
||||
}
|
||||
|
||||
InputEvent ev{};
|
||||
ev.type = INPUT_EVENT_KIND_KEY;
|
||||
ev.u.key.down = !k.Flags;
|
||||
ev.u.key.key.type = KEY_VALUE_KIND_QCODE;
|
||||
ev.u.key.key.u.qcode = qcode;
|
||||
|
||||
hs->kbd.eh_entry(hs, &ev);
|
||||
}
|
||||
|
||||
static void SendPointerEvent(InputEvent &ev, HIDState *hs)
|
||||
{
|
||||
if (hs->ptr.eh_entry) {
|
||||
hs->ptr.eh_entry(hs, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseRawInputMS(RAWMOUSE &m, HIDState *hs)
|
||||
{
|
||||
int b = 0, z = 0;
|
||||
InputEvent ev{};
|
||||
|
||||
if (m.usButtonFlags & RI_MOUSE_WHEEL)
|
||||
z = (short)m.usButtonData / WHEEL_DELTA;
|
||||
|
||||
//OSDebugOut(TEXT("mouse: %d %d %u %hd\n"), m.lLastX, m.lLastY, m.ulButtons, z);
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_BTN;
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (z != 0)
|
||||
{
|
||||
ev.u.btn.button = (z < 0) ? INPUT_BUTTON_WHEEL_DOWN : INPUT_BUTTON_WHEEL_UP;
|
||||
for (int i = 0; i < z; i++)
|
||||
static void ParseRawInputMS(RAWMOUSE& m, HIDState* hs)
|
||||
{
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
ev.u.btn.down = false; // TODO needs an UP event?
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
}
|
||||
int b = 0, z = 0;
|
||||
InputEvent ev{};
|
||||
|
||||
if (m.usFlags & MOUSE_MOVE_ABSOLUTE)
|
||||
{
|
||||
/*ev.type = INPUT_EVENT_KIND_ABS;
|
||||
if (m.usButtonFlags & RI_MOUSE_WHEEL)
|
||||
z = (short)m.usButtonData / WHEEL_DELTA;
|
||||
|
||||
//OSDebugOut(TEXT("mouse: %d %d %u %hd\n"), m.lLastX, m.lLastY, m.ulButtons, z);
|
||||
|
||||
ev.type = INPUT_EVENT_KIND_BTN;
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_LEFT;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_RIGHT;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (m.ulButtons & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
if (m.ulButtons & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
{
|
||||
ev.u.btn.button = INPUT_BUTTON_MIDDLE;
|
||||
ev.u.btn.down = false;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
if (z != 0)
|
||||
{
|
||||
ev.u.btn.button = (z < 0) ? INPUT_BUTTON_WHEEL_DOWN : INPUT_BUTTON_WHEEL_UP;
|
||||
for (int i = 0; i < z; i++)
|
||||
{
|
||||
ev.u.btn.down = true;
|
||||
SendPointerEvent(ev, hs);
|
||||
ev.u.btn.down = false; // TODO needs an UP event?
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
}
|
||||
|
||||
if (m.usFlags & MOUSE_MOVE_ABSOLUTE)
|
||||
{
|
||||
/*ev.type = INPUT_EVENT_KIND_ABS;
|
||||
ev.u.abs.axis = INPUT_AXIS_X;
|
||||
ev.u.abs.value = m.lLastX;
|
||||
SendPointerEvent(ev, hs);
|
||||
|
@ -235,53 +253,54 @@ static void ParseRawInputMS(RAWMOUSE &m, HIDState *hs)
|
|||
ev.u.abs.axis = INPUT_AXIS_Y;
|
||||
ev.u.abs.value = m.lLastY;
|
||||
SendPointerEvent(ev, hs);*/
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.type = INPUT_EVENT_KIND_REL;
|
||||
ev.u.rel.axis = INPUT_AXIS_X;
|
||||
ev.u.rel.value = m.lLastX;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.type = INPUT_EVENT_KIND_REL;
|
||||
ev.u.rel.axis = INPUT_AXIS_X;
|
||||
ev.u.rel.value = m.lLastX;
|
||||
SendPointerEvent(ev, hs);
|
||||
|
||||
ev.u.rel.axis = INPUT_AXIS_Y;
|
||||
ev.u.rel.value = m.lLastY;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
ev.u.rel.axis = INPUT_AXIS_Y;
|
||||
ev.u.rel.value = m.lLastY;
|
||||
SendPointerEvent(ev, hs);
|
||||
}
|
||||
|
||||
|
||||
if (hs->ptr.eh_sync)
|
||||
hs->ptr.eh_sync(hs);
|
||||
}
|
||||
if (hs->ptr.eh_sync)
|
||||
hs->ptr.eh_sync(hs);
|
||||
}
|
||||
|
||||
void RawInput::ParseRawInput(PRAWINPUT pRawInput)
|
||||
{
|
||||
if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
|
||||
ParseRawInputKB(pRawInput->data.keyboard, mHIDState);
|
||||
else if (pRawInput->header.dwType == RIM_TYPEMOUSE)
|
||||
ParseRawInputMS(pRawInput->data.mouse, mHIDState);
|
||||
// else
|
||||
// ParseRawInput(pRawInput, mHIDState);
|
||||
}
|
||||
void RawInput::ParseRawInput(PRAWINPUT pRawInput)
|
||||
{
|
||||
if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
|
||||
ParseRawInputKB(pRawInput->data.keyboard, mHIDState);
|
||||
else if (pRawInput->header.dwType == RIM_TYPEMOUSE)
|
||||
ParseRawInputMS(pRawInput->data.mouse, mHIDState);
|
||||
// else
|
||||
// ParseRawInput(pRawInput, mHIDState);
|
||||
}
|
||||
|
||||
int RawInput::Open()
|
||||
{
|
||||
Close();
|
||||
shared::rawinput::RegisterCallback(this);
|
||||
return 0;
|
||||
}
|
||||
int RawInput::Open()
|
||||
{
|
||||
Close();
|
||||
shared::rawinput::RegisterCallback(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RawInput::Close()
|
||||
{
|
||||
Reset();
|
||||
shared::rawinput::UnregisterCallback(this);
|
||||
return 0;
|
||||
}
|
||||
int RawInput::Close()
|
||||
{
|
||||
Reset();
|
||||
shared::rawinput::UnregisterCallback(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RawInput::Configure(int port, const char* dev_type, HIDType type, void *data)
|
||||
{
|
||||
Win32Handles *h = (Win32Handles*)data;
|
||||
INT_PTR res = RESULT_CANCELED;
|
||||
return res;
|
||||
}
|
||||
int RawInput::Configure(int port, const char* dev_type, HIDType type, void* data)
|
||||
{
|
||||
Win32Handles* h = (Win32Handles*)data;
|
||||
INT_PTR res = RESULT_CANCELED;
|
||||
return res;
|
||||
}
|
||||
|
||||
}} //namespace
|
||||
} // namespace raw
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -17,33 +17,38 @@
|
|||
#include "../hidproxy.h"
|
||||
#include "../usb-hid.h"
|
||||
|
||||
namespace usb_hid { namespace raw {
|
||||
|
||||
static const char* APINAME = "rawinput";
|
||||
|
||||
class RawInput : public UsbHID, shared::rawinput::ParseRawInputCB
|
||||
namespace usb_hid
|
||||
{
|
||||
public:
|
||||
RawInput(int port, const char* dev_type) : UsbHID(port, dev_type)
|
||||
namespace raw
|
||||
{
|
||||
}
|
||||
~RawInput()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
int Open();
|
||||
int Close();
|
||||
// int TokenIn(uint8_t *buf, int len);
|
||||
int TokenOut(const uint8_t *data, int len);
|
||||
int Reset() { return 0; }
|
||||
void ParseRawInput(PRAWINPUT pRawInput);
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Raw Input");
|
||||
}
|
||||
static const char* APINAME = "rawinput";
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType, void *data);
|
||||
};
|
||||
class RawInput : public UsbHID, shared::rawinput::ParseRawInputCB
|
||||
{
|
||||
public:
|
||||
RawInput(int port, const char* dev_type)
|
||||
: UsbHID(port, dev_type)
|
||||
{
|
||||
}
|
||||
~RawInput()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
int Open();
|
||||
int Close();
|
||||
// int TokenIn(uint8_t *buf, int len);
|
||||
int TokenOut(const uint8_t* data, int len);
|
||||
int Reset() { return 0; }
|
||||
void ParseRawInput(PRAWINPUT pRawInput);
|
||||
|
||||
}} // namespace
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Raw Input");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, HIDType, void* data);
|
||||
};
|
||||
|
||||
} // namespace raw
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "vl.h"
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
extern "C"{
|
||||
extern "C" {
|
||||
#include "../ddk/hidsdi.h"
|
||||
}
|
||||
|
||||
|
@ -33,13 +33,13 @@ extern "C"{
|
|||
|
||||
#if 0
|
||||
/* HID interface requests */
|
||||
#define GET_REPORT 0xa101
|
||||
#define GET_IDLE 0xa102
|
||||
#define GET_REPORT 0xa101
|
||||
#define GET_IDLE 0xa102
|
||||
#define GET_PROTOCOL 0xa103
|
||||
#define SET_IDLE 0x210a
|
||||
#define SET_IDLE 0x210a
|
||||
#define SET_PROTOCOL 0x210b
|
||||
|
||||
#define USB_MOUSE 1
|
||||
#define USB_MOUSE 1
|
||||
#define USB_TABLET 2
|
||||
|
||||
typedef struct USBKeyboardState {
|
||||
|
@ -350,7 +350,7 @@ static const uint8_t vk_to_key_code[] = {
|
|||
0x00, //FAIL: 0x00
|
||||
};
|
||||
#else
|
||||
# ifdef ENABLE_KEYPAD_Fx
|
||||
#ifdef ENABLE_KEYPAD_Fx
|
||||
static const unsigned char scan_to_usb[] = {
|
||||
0x00,0x29,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x2f,0x30,0x2a,0x2b,
|
||||
0x14,0x1a,0x08,0x15,0x17,0x1c,0x18,0x0c,0x12,0x13,0x33,0x2e,0x28,0xe0,0x04,0x16,
|
||||
|
@ -401,7 +401,7 @@ static const unsigned char scan_to_usb[] = {
|
|||
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,
|
||||
};
|
||||
# else
|
||||
#else
|
||||
static const unsigned char scan_to_usb[] = {
|
||||
0x00,0x29,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x2f,0x30,0x2a,0x2b,
|
||||
0x14,0x1a,0x08,0x15,0x17,0x1c,0x18,0x0c,0x12,0x13,0x33,0x2e,0x28,0xe0,0x04,0x16,
|
||||
|
@ -452,7 +452,7 @@ static const unsigned char scan_to_usb[] = {
|
|||
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,
|
||||
};
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* mostly the same values as the Bochs USB Keyboard device */
|
||||
|
@ -623,9 +623,9 @@ static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
|
|||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
#define BUZZER_VID 0x054C
|
||||
#define BUZZER_PID 0x1000
|
||||
#define BUZZER_PID2 0x0002
|
||||
#define BUZZER_VID 0x054C
|
||||
#define BUZZER_PID 0x1000
|
||||
#define BUZZER_PID2 0x0002
|
||||
|
||||
unsigned char comp_data[6];
|
||||
HANDLE usb_buzzer=(HANDLE)-1;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,73 +19,78 @@
|
|||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace usb_hid {
|
||||
|
||||
enum HIDType
|
||||
namespace usb_hid
|
||||
{
|
||||
HIDTYPE_KBD,
|
||||
HIDTYPE_MOUSE,
|
||||
};
|
||||
|
||||
class UsbHID
|
||||
{
|
||||
public:
|
||||
UsbHID(int port, const char* dev_type) : mPort(port), mDevType(dev_type) {}
|
||||
virtual ~UsbHID() {}
|
||||
virtual int Open() = 0;
|
||||
virtual int Close() = 0;
|
||||
// virtual int TokenIn(uint8_t *buf, int len) = 0;
|
||||
virtual int TokenOut(const uint8_t *data, int len) = 0;
|
||||
virtual int Reset() = 0;
|
||||
enum HIDType
|
||||
{
|
||||
HIDTYPE_KBD,
|
||||
HIDTYPE_MOUSE,
|
||||
};
|
||||
|
||||
virtual int Port() { return mPort; }
|
||||
virtual void Port(int port) { mPort = port; }
|
||||
virtual void SetHIDState(HIDState *hs) { mHIDState = hs; }
|
||||
virtual void SetHIDType(HIDType t) { mHIDType = t; }
|
||||
class UsbHID
|
||||
{
|
||||
public:
|
||||
UsbHID(int port, const char* dev_type)
|
||||
: mPort(port)
|
||||
, mDevType(dev_type)
|
||||
{
|
||||
}
|
||||
virtual ~UsbHID() {}
|
||||
virtual int Open() = 0;
|
||||
virtual int Close() = 0;
|
||||
// virtual int TokenIn(uint8_t *buf, int len) = 0;
|
||||
virtual int TokenOut(const uint8_t* data, int len) = 0;
|
||||
virtual int Reset() = 0;
|
||||
|
||||
protected:
|
||||
int mPort;
|
||||
HIDState *mHIDState;
|
||||
HIDType mHIDType;
|
||||
const char *mDevType;
|
||||
};
|
||||
virtual int Port() { return mPort; }
|
||||
virtual void Port(int port) { mPort = port; }
|
||||
virtual void SetHIDState(HIDState* hs) { mHIDState = hs; }
|
||||
virtual void SetHIDType(HIDType t) { mHIDType = t; }
|
||||
|
||||
class HIDKbdDevice
|
||||
{
|
||||
public:
|
||||
virtual ~HIDKbdDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("HID Keyboard");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "hidkbd";
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
protected:
|
||||
int mPort;
|
||||
HIDState* mHIDState;
|
||||
HIDType mHIDType;
|
||||
const char* mDevType;
|
||||
};
|
||||
|
||||
class HIDMouseDevice
|
||||
{
|
||||
public:
|
||||
virtual ~HIDMouseDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("HID Mouse");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "hidmouse";
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
class HIDKbdDevice
|
||||
{
|
||||
public:
|
||||
virtual ~HIDKbdDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("HID Keyboard");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "hidkbd";
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
}
|
||||
class HIDMouseDevice
|
||||
{
|
||||
public:
|
||||
virtual ~HIDMouseDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("HID Mouse");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "hidmouse";
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
} // namespace usb_hid
|
||||
|
|
|
@ -21,106 +21,106 @@
|
|||
|
||||
|
||||
/* Audio Interface Subclass Codes */
|
||||
#define AUDIO_SUBCLASS_UNDEFINED 0x00
|
||||
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
|
||||
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
|
||||
#define AUDIO_SUBCLASS_MIDISTREAMING 0x03
|
||||
#define AUDIO_SUBCLASS_UNDEFINED 0x00
|
||||
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
|
||||
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
|
||||
#define AUDIO_SUBCLASS_MIDISTREAMING 0x03
|
||||
|
||||
/* Audio Interface Protocol Codes */
|
||||
#define AUDIO_PROTOCOL_UNDEFINED 0x00
|
||||
#define AUDIO_PROTOCOL_UNDEFINED 0x00
|
||||
|
||||
|
||||
/* Audio Descriptor Types */
|
||||
#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20
|
||||
#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21
|
||||
#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22
|
||||
#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23
|
||||
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
|
||||
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
|
||||
#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20
|
||||
#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21
|
||||
#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22
|
||||
#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23
|
||||
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
|
||||
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
|
||||
|
||||
|
||||
/* Audio Control Interface Descriptor Subtypes */
|
||||
#define AUDIO_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_CONTROL_HEADER 0x01
|
||||
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02
|
||||
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03
|
||||
#define AUDIO_CONTROL_MIXER_UNIT 0x04
|
||||
#define AUDIO_CONTROL_SELECTOR_UNIT 0x05
|
||||
#define AUDIO_CONTROL_FEATURE_UNIT 0x06
|
||||
#define AUDIO_CONTROL_PROCESSING_UNIT 0x07
|
||||
#define AUDIO_CONTROL_EXTENSION_UNIT 0x08
|
||||
#define AUDIO_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_CONTROL_HEADER 0x01
|
||||
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02
|
||||
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03
|
||||
#define AUDIO_CONTROL_MIXER_UNIT 0x04
|
||||
#define AUDIO_CONTROL_SELECTOR_UNIT 0x05
|
||||
#define AUDIO_CONTROL_FEATURE_UNIT 0x06
|
||||
#define AUDIO_CONTROL_PROCESSING_UNIT 0x07
|
||||
#define AUDIO_CONTROL_EXTENSION_UNIT 0x08
|
||||
|
||||
/* Audio Streaming Interface Descriptor Subtypes */
|
||||
#define AUDIO_STREAMING_UNDEFINED 0x00
|
||||
#define AUDIO_STREAMING_GENERAL 0x01
|
||||
#define AUDIO_STREAMING_FORMAT_TYPE 0x02
|
||||
#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03
|
||||
#define AUDIO_STREAMING_UNDEFINED 0x00
|
||||
#define AUDIO_STREAMING_GENERAL 0x01
|
||||
#define AUDIO_STREAMING_FORMAT_TYPE 0x02
|
||||
#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03
|
||||
|
||||
/* Audio Endpoint Descriptor Subtypes */
|
||||
#define AUDIO_ENDPOINT_UNDEFINED 0x00
|
||||
#define AUDIO_ENDPOINT_GENERAL 0x01
|
||||
#define AUDIO_ENDPOINT_UNDEFINED 0x00
|
||||
#define AUDIO_ENDPOINT_GENERAL 0x01
|
||||
|
||||
|
||||
/* Audio Descriptor Sizes */
|
||||
#define AUDIO_CONTROL_INTERFACE_DESC_SZ(n) 0x08+n
|
||||
#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07
|
||||
#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C
|
||||
#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09
|
||||
#define AUDIO_MIXER_UNIT_DESC_SZ(p,n) 0x0A+p+n
|
||||
#define AUDIO_SELECTOR_UNIT_DESC_SZ(p) 0x06+p
|
||||
#define AUDIO_FEATURE_UNIT_DESC_SZ(ch,n) 0x07+(ch+1)*n
|
||||
#define AUDIO_PROCESSING_UNIT_DESC_SZ(p,n,x) 0x0D+p+n+x
|
||||
#define AUDIO_EXTENSION_UNIT_DESC_SZ(p,n) 0x0D+p+n
|
||||
#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09
|
||||
#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07
|
||||
#define AUDIO_CONTROL_INTERFACE_DESC_SZ(n) 0x08 + n
|
||||
#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07
|
||||
#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C
|
||||
#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09
|
||||
#define AUDIO_MIXER_UNIT_DESC_SZ(p, n) 0x0A + p + n
|
||||
#define AUDIO_SELECTOR_UNIT_DESC_SZ(p) 0x06 + p
|
||||
#define AUDIO_FEATURE_UNIT_DESC_SZ(ch, n) 0x07 + (ch + 1) * n
|
||||
#define AUDIO_PROCESSING_UNIT_DESC_SZ(p, n, x) 0x0D + p + n + x
|
||||
#define AUDIO_EXTENSION_UNIT_DESC_SZ(p, n) 0x0D + p + n
|
||||
#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09
|
||||
#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07
|
||||
|
||||
|
||||
/* Audio Processing Unit Process Types */
|
||||
#define AUDIO_UNDEFINED_PROCESS 0x00
|
||||
#define AUDIO_UP_DOWN_MIX_PROCESS 0x01
|
||||
#define AUDIO_DOLBY_PROLOGIC_PROCESS 0x02
|
||||
#define AUDIO_3D_STEREO_PROCESS 0x03
|
||||
#define AUDIO_REVERBERATION_PROCESS 0x04
|
||||
#define AUDIO_CHORUS_PROCESS 0x05
|
||||
#define AUDIO_DYN_RANGE_COMP_PROCESS 0x06
|
||||
#define AUDIO_UNDEFINED_PROCESS 0x00
|
||||
#define AUDIO_UP_DOWN_MIX_PROCESS 0x01
|
||||
#define AUDIO_DOLBY_PROLOGIC_PROCESS 0x02
|
||||
#define AUDIO_3D_STEREO_PROCESS 0x03
|
||||
#define AUDIO_REVERBERATION_PROCESS 0x04
|
||||
#define AUDIO_CHORUS_PROCESS 0x05
|
||||
#define AUDIO_DYN_RANGE_COMP_PROCESS 0x06
|
||||
|
||||
|
||||
/* Audio Request Codes */
|
||||
#define AUDIO_REQUEST_UNDEFINED 0x00
|
||||
#define AUDIO_REQUEST_SET_CUR 0x01
|
||||
#define AUDIO_REQUEST_GET_CUR 0x81
|
||||
#define AUDIO_REQUEST_SET_MIN 0x02
|
||||
#define AUDIO_REQUEST_GET_MIN 0x82
|
||||
#define AUDIO_REQUEST_SET_MAX 0x03
|
||||
#define AUDIO_REQUEST_GET_MAX 0x83
|
||||
#define AUDIO_REQUEST_SET_RES 0x04
|
||||
#define AUDIO_REQUEST_GET_RES 0x84
|
||||
#define AUDIO_REQUEST_SET_MEM 0x05
|
||||
#define AUDIO_REQUEST_GET_MEM 0x85
|
||||
#define AUDIO_REQUEST_GET_STAT 0xFF
|
||||
#define AUDIO_REQUEST_UNDEFINED 0x00
|
||||
#define AUDIO_REQUEST_SET_CUR 0x01
|
||||
#define AUDIO_REQUEST_GET_CUR 0x81
|
||||
#define AUDIO_REQUEST_SET_MIN 0x02
|
||||
#define AUDIO_REQUEST_GET_MIN 0x82
|
||||
#define AUDIO_REQUEST_SET_MAX 0x03
|
||||
#define AUDIO_REQUEST_GET_MAX 0x83
|
||||
#define AUDIO_REQUEST_SET_RES 0x04
|
||||
#define AUDIO_REQUEST_GET_RES 0x84
|
||||
#define AUDIO_REQUEST_SET_MEM 0x05
|
||||
#define AUDIO_REQUEST_GET_MEM 0x85
|
||||
#define AUDIO_REQUEST_GET_STAT 0xFF
|
||||
|
||||
|
||||
/* Audio Control Selector Codes */
|
||||
#define AUDIO_CONTROL_UNDEFINED 0x00 /* Common Selector */
|
||||
#define AUDIO_CONTROL_UNDEFINED 0x00 /* Common Selector */
|
||||
|
||||
/* Terminal Control Selectors */
|
||||
#define AUDIO_COPY_PROTECT_CONTROL 0x01
|
||||
#define AUDIO_COPY_PROTECT_CONTROL 0x01
|
||||
|
||||
/* Feature Unit Control Selectors */
|
||||
#define AUDIO_MUTE_CONTROL 0x01
|
||||
#define AUDIO_VOLUME_CONTROL 0x02
|
||||
#define AUDIO_BASS_CONTROL 0x03
|
||||
#define AUDIO_MID_CONTROL 0x04
|
||||
#define AUDIO_TREBLE_CONTROL 0x05
|
||||
#define AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06
|
||||
#define AUDIO_AUTOMATIC_GAIN_CONTROL 0x07
|
||||
#define AUDIO_DELAY_CONTROL 0x08
|
||||
#define AUDIO_BASS_BOOST_CONTROL 0x09
|
||||
#define AUDIO_LOUDNESS_CONTROL 0x0A
|
||||
#define AUDIO_MUTE_CONTROL 0x01
|
||||
#define AUDIO_VOLUME_CONTROL 0x02
|
||||
#define AUDIO_BASS_CONTROL 0x03
|
||||
#define AUDIO_MID_CONTROL 0x04
|
||||
#define AUDIO_TREBLE_CONTROL 0x05
|
||||
#define AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06
|
||||
#define AUDIO_AUTOMATIC_GAIN_CONTROL 0x07
|
||||
#define AUDIO_DELAY_CONTROL 0x08
|
||||
#define AUDIO_BASS_BOOST_CONTROL 0x09
|
||||
#define AUDIO_LOUDNESS_CONTROL 0x0A
|
||||
|
||||
/* Processing Unit Control Selectors: */
|
||||
#define AUDIO_ENABLE_CONTROL 0x01 /* Common Selector */
|
||||
#define AUDIO_MODE_SELECT_CONTROL 0x02 /* Common Selector */
|
||||
#define AUDIO_ENABLE_CONTROL 0x01 /* Common Selector */
|
||||
#define AUDIO_MODE_SELECT_CONTROL 0x02 /* Common Selector */
|
||||
|
||||
/* - Up/Down-mix Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
|
@ -132,127 +132,127 @@
|
|||
|
||||
/* - 3D Stereo Extender Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
#define AUDIO_SPACIOUSNESS_CONTROL 0x02
|
||||
#define AUDIO_SPACIOUSNESS_CONTROL 0x02
|
||||
|
||||
/* - Reverberation Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
#define AUDIO_REVERB_LEVEL_CONTROL 0x02
|
||||
#define AUDIO_REVERB_TIME_CONTROL 0x03
|
||||
#define AUDIO_REVERB_FEEDBACK_CONTROL 0x04
|
||||
#define AUDIO_REVERB_LEVEL_CONTROL 0x02
|
||||
#define AUDIO_REVERB_TIME_CONTROL 0x03
|
||||
#define AUDIO_REVERB_FEEDBACK_CONTROL 0x04
|
||||
|
||||
/* - Chorus Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
#define AUDIO_CHORUS_LEVEL_CONTROL 0x02
|
||||
#define AUDIO_SHORUS_RATE_CONTROL 0x03
|
||||
#define AUDIO_CHORUS_DEPTH_CONTROL 0x04
|
||||
#define AUDIO_CHORUS_LEVEL_CONTROL 0x02
|
||||
#define AUDIO_SHORUS_RATE_CONTROL 0x03
|
||||
#define AUDIO_CHORUS_DEPTH_CONTROL 0x04
|
||||
|
||||
/* - Dynamic Range Compressor Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
#define AUDIO_COMPRESSION_RATE_CONTROL 0x02
|
||||
#define AUDIO_MAX_AMPL_CONTROL 0x03
|
||||
#define AUDIO_THRESHOLD_CONTROL 0x04
|
||||
#define AUDIO_ATTACK_TIME_CONTROL 0x05
|
||||
#define AUDIO_RELEASE_TIME_CONTROL 0x06
|
||||
#define AUDIO_COMPRESSION_RATE_CONTROL 0x02
|
||||
#define AUDIO_MAX_AMPL_CONTROL 0x03
|
||||
#define AUDIO_THRESHOLD_CONTROL 0x04
|
||||
#define AUDIO_ATTACK_TIME_CONTROL 0x05
|
||||
#define AUDIO_RELEASE_TIME_CONTROL 0x06
|
||||
|
||||
/* Extension Unit Control Selectors */
|
||||
/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */
|
||||
|
||||
/* Endpoint Control Selectors */
|
||||
#define AUDIO_SAMPLING_FREQ_CONTROL 0x01
|
||||
#define AUDIO_PITCH_CONTROL 0x02
|
||||
#define AUDIO_SAMPLING_FREQ_CONTROL 0x01
|
||||
#define AUDIO_PITCH_CONTROL 0x02
|
||||
|
||||
|
||||
/* Audio Format Specific Control Selectors */
|
||||
|
||||
/* MPEG Control Selectors */
|
||||
#define AUDIO_MPEG_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_MPEG_DUAL_CHANNEL_CONTROL 0x01
|
||||
#define AUDIO_MPEG_SECOND_STEREO_CONTROL 0x02
|
||||
#define AUDIO_MPEG_MULTILINGUAL_CONTROL 0x03
|
||||
#define AUDIO_MPEG_DYN_RANGE_CONTROL 0x04
|
||||
#define AUDIO_MPEG_SCALING_CONTROL 0x05
|
||||
#define AUDIO_MPEG_HILO_SCALING_CONTROL 0x06
|
||||
#define AUDIO_MPEG_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_MPEG_DUAL_CHANNEL_CONTROL 0x01
|
||||
#define AUDIO_MPEG_SECOND_STEREO_CONTROL 0x02
|
||||
#define AUDIO_MPEG_MULTILINGUAL_CONTROL 0x03
|
||||
#define AUDIO_MPEG_DYN_RANGE_CONTROL 0x04
|
||||
#define AUDIO_MPEG_SCALING_CONTROL 0x05
|
||||
#define AUDIO_MPEG_HILO_SCALING_CONTROL 0x06
|
||||
|
||||
/* AC-3 Control Selectors */
|
||||
#define AUDIO_AC3_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_AC3_MODE_CONTROL 0x01
|
||||
#define AUDIO_AC3_DYN_RANGE_CONTROL 0x02
|
||||
#define AUDIO_AC3_SCALING_CONTROL 0x03
|
||||
#define AUDIO_AC3_HILO_SCALING_CONTROL 0x04
|
||||
#define AUDIO_AC3_CONTROL_UNDEFINED 0x00
|
||||
#define AUDIO_AC3_MODE_CONTROL 0x01
|
||||
#define AUDIO_AC3_DYN_RANGE_CONTROL 0x02
|
||||
#define AUDIO_AC3_SCALING_CONTROL 0x03
|
||||
#define AUDIO_AC3_HILO_SCALING_CONTROL 0x04
|
||||
|
||||
|
||||
/* Audio Format Types */
|
||||
#define AUDIO_FORMAT_TYPE_UNDEFINED 0x00
|
||||
#define AUDIO_FORMAT_TYPE_I 0x01
|
||||
#define AUDIO_FORMAT_TYPE_II 0x02
|
||||
#define AUDIO_FORMAT_TYPE_III 0x03
|
||||
#define AUDIO_FORMAT_TYPE_UNDEFINED 0x00
|
||||
#define AUDIO_FORMAT_TYPE_I 0x01
|
||||
#define AUDIO_FORMAT_TYPE_II 0x02
|
||||
#define AUDIO_FORMAT_TYPE_III 0x03
|
||||
|
||||
|
||||
/* Audio Format Type Descriptor Sizes */
|
||||
#define AUDIO_FORMAT_TYPE_I_DESC_SZ(n) 0x08+(n*3)
|
||||
#define AUDIO_FORMAT_TYPE_II_DESC_SZ(n) 0x09+(n*3)
|
||||
#define AUDIO_FORMAT_TYPE_III_DESC_SZ(n) 0x08+(n*3)
|
||||
#define AUDIO_FORMAT_MPEG_DESC_SIZE 0x09
|
||||
#define AUDIO_FORMAT_AC3_DESC_SIZE 0x0A
|
||||
#define AUDIO_FORMAT_TYPE_I_DESC_SZ(n) 0x08 + (n * 3)
|
||||
#define AUDIO_FORMAT_TYPE_II_DESC_SZ(n) 0x09 + (n * 3)
|
||||
#define AUDIO_FORMAT_TYPE_III_DESC_SZ(n) 0x08 + (n * 3)
|
||||
#define AUDIO_FORMAT_MPEG_DESC_SIZE 0x09
|
||||
#define AUDIO_FORMAT_AC3_DESC_SIZE 0x0A
|
||||
|
||||
|
||||
/* Audio Data Format Codes */
|
||||
|
||||
/* Audio Data Format Type I Codes */
|
||||
#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000
|
||||
#define AUDIO_FORMAT_PCM 0x0001
|
||||
#define AUDIO_FORMAT_PCM8 0x0002
|
||||
#define AUDIO_FORMAT_IEEE_FLOAT 0x0003
|
||||
#define AUDIO_FORMAT_ALAW 0x0004
|
||||
#define AUDIO_FORMAT_MULAW 0x0005
|
||||
#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000
|
||||
#define AUDIO_FORMAT_PCM 0x0001
|
||||
#define AUDIO_FORMAT_PCM8 0x0002
|
||||
#define AUDIO_FORMAT_IEEE_FLOAT 0x0003
|
||||
#define AUDIO_FORMAT_ALAW 0x0004
|
||||
#define AUDIO_FORMAT_MULAW 0x0005
|
||||
|
||||
/* Audio Data Format Type II Codes */
|
||||
#define AUDIO_FORMAT_TYPE_II_UNDEFINED 0x1000
|
||||
#define AUDIO_FORMAT_MPEG 0x1001
|
||||
#define AUDIO_FORMAT_AC3 0x1002
|
||||
#define AUDIO_FORMAT_TYPE_II_UNDEFINED 0x1000
|
||||
#define AUDIO_FORMAT_MPEG 0x1001
|
||||
#define AUDIO_FORMAT_AC3 0x1002
|
||||
|
||||
/* Audio Data Format Type III Codes */
|
||||
#define AUDIO_FORMAT_TYPE_III_UNDEFINED 0x2000
|
||||
#define AUDIO_FORMAT_IEC1937_AC3 0x2001
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG1_L1 0x2002
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG1_L2_3 0x2003
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_L1_LS 0x2005
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_L2_3 0x2006
|
||||
#define AUDIO_FORMAT_TYPE_III_UNDEFINED 0x2000
|
||||
#define AUDIO_FORMAT_IEC1937_AC3 0x2001
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG1_L1 0x2002
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG1_L2_3 0x2003
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_L1_LS 0x2005
|
||||
#define AUDIO_FORMAT_IEC1937_MPEG2_L2_3 0x2006
|
||||
|
||||
|
||||
/* Predefined Audio Channel Configuration Bits */
|
||||
#define AUDIO_CHANNEL_M 0x0000 /* Mono */
|
||||
#define AUDIO_CHANNEL_L 0x0001 /* Left Front */
|
||||
#define AUDIO_CHANNEL_R 0x0002 /* Right Front */
|
||||
#define AUDIO_CHANNEL_C 0x0004 /* Center Front */
|
||||
#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */
|
||||
#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */
|
||||
#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */
|
||||
#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */
|
||||
#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */
|
||||
#define AUDIO_CHANNEL_S 0x0100 /* Surround */
|
||||
#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */
|
||||
#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */
|
||||
#define AUDIO_CHANNEL_T 0x0800 /* Top */
|
||||
#define AUDIO_CHANNEL_M 0x0000 /* Mono */
|
||||
#define AUDIO_CHANNEL_L 0x0001 /* Left Front */
|
||||
#define AUDIO_CHANNEL_R 0x0002 /* Right Front */
|
||||
#define AUDIO_CHANNEL_C 0x0004 /* Center Front */
|
||||
#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */
|
||||
#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */
|
||||
#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */
|
||||
#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */
|
||||
#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */
|
||||
#define AUDIO_CHANNEL_S 0x0100 /* Surround */
|
||||
#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */
|
||||
#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */
|
||||
#define AUDIO_CHANNEL_T 0x0800 /* Top */
|
||||
|
||||
|
||||
/* Feature Unit Control Bits */
|
||||
#define AUDIO_CONTROL_MUTE 0x0001
|
||||
#define AUDIO_CONTROL_VOLUME 0x0002
|
||||
#define AUDIO_CONTROL_BASS 0x0004
|
||||
#define AUDIO_CONTROL_MID 0x0008
|
||||
#define AUDIO_CONTROL_TREBLE 0x0010
|
||||
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
|
||||
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
|
||||
#define AUDIO_CONTROL_DEALY 0x0080
|
||||
#define AUDIO_CONTROL_BASS_BOOST 0x0100
|
||||
#define AUDIO_CONTROL_LOUDNESS 0x0200
|
||||
#define AUDIO_CONTROL_MUTE 0x0001
|
||||
#define AUDIO_CONTROL_VOLUME 0x0002
|
||||
#define AUDIO_CONTROL_BASS 0x0004
|
||||
#define AUDIO_CONTROL_MID 0x0008
|
||||
#define AUDIO_CONTROL_TREBLE 0x0010
|
||||
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
|
||||
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
|
||||
#define AUDIO_CONTROL_DEALY 0x0080
|
||||
#define AUDIO_CONTROL_BASS_BOOST 0x0100
|
||||
#define AUDIO_CONTROL_LOUDNESS 0x0200
|
||||
|
||||
/* Processing Unit Control Bits: */
|
||||
#define AUDIO_CONTROL_ENABLE 0x0001 /* Common Bit */
|
||||
#define AUDIO_CONTROL_MODE_SELECT 0x0002 /* Common Bit */
|
||||
#define AUDIO_CONTROL_ENABLE 0x0001 /* Common Bit */
|
||||
#define AUDIO_CONTROL_MODE_SELECT 0x0002 /* Common Bit */
|
||||
|
||||
/* - Up/Down-mix Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
|
@ -264,109 +264,109 @@
|
|||
|
||||
/* - 3D Stereo Extender Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
#define AUDIO_CONTROL_SPACIOUSNESS 0x0002
|
||||
#define AUDIO_CONTROL_SPACIOUSNESS 0x0002
|
||||
|
||||
/* - Reverberation Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
#define AUDIO_CONTROL_REVERB_TYPE 0x0002
|
||||
#define AUDIO_CONTROL_REVERB_LEVEL 0x0004
|
||||
#define AUDIO_CONTROL_REVERB_TIME 0x0008
|
||||
#define AUDIO_CONTROL_REVERB_FEEDBACK 0x0010
|
||||
#define AUDIO_CONTROL_REVERB_TYPE 0x0002
|
||||
#define AUDIO_CONTROL_REVERB_LEVEL 0x0004
|
||||
#define AUDIO_CONTROL_REVERB_TIME 0x0008
|
||||
#define AUDIO_CONTROL_REVERB_FEEDBACK 0x0010
|
||||
|
||||
/* - Chorus Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
#define AUDIO_CONTROL_CHORUS_LEVEL 0x0002
|
||||
#define AUDIO_CONTROL_SHORUS_RATE 0x0004
|
||||
#define AUDIO_CONTROL_CHORUS_DEPTH 0x0008
|
||||
#define AUDIO_CONTROL_CHORUS_LEVEL 0x0002
|
||||
#define AUDIO_CONTROL_SHORUS_RATE 0x0004
|
||||
#define AUDIO_CONTROL_CHORUS_DEPTH 0x0008
|
||||
|
||||
/* - Dynamic Range Compressor Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
#define AUDIO_CONTROL_COMPRESSION_RATE 0x0002
|
||||
#define AUDIO_CONTROL_MAX_AMPL 0x0004
|
||||
#define AUDIO_CONTROL_THRESHOLD 0x0008
|
||||
#define AUDIO_CONTROL_ATTACK_TIME 0x0010
|
||||
#define AUDIO_CONTROL_RELEASE_TIME 0x0020
|
||||
#define AUDIO_CONTROL_COMPRESSION_RATE 0x0002
|
||||
#define AUDIO_CONTROL_MAX_AMPL 0x0004
|
||||
#define AUDIO_CONTROL_THRESHOLD 0x0008
|
||||
#define AUDIO_CONTROL_ATTACK_TIME 0x0010
|
||||
#define AUDIO_CONTROL_RELEASE_TIME 0x0020
|
||||
|
||||
/* Extension Unit Control Bits */
|
||||
/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */
|
||||
|
||||
/* Endpoint Control Bits */
|
||||
#define AUDIO_CONTROL_SAMPLING_FREQ 0x01
|
||||
#define AUDIO_CONTROL_PITCH 0x02
|
||||
#define AUDIO_MAX_PACKETS_ONLY 0x80
|
||||
#define AUDIO_CONTROL_SAMPLING_FREQ 0x01
|
||||
#define AUDIO_CONTROL_PITCH 0x02
|
||||
#define AUDIO_MAX_PACKETS_ONLY 0x80
|
||||
|
||||
|
||||
/* Audio Terminal Types */
|
||||
|
||||
/* USB Terminal Types */
|
||||
#define AUDIO_TERMINAL_USB_UNDEFINED 0x0100
|
||||
#define AUDIO_TERMINAL_USB_STREAMING 0x0101
|
||||
#define AUDIO_TERMINAL_USB_VENDOR_SPECIFIC 0x01FF
|
||||
#define AUDIO_TERMINAL_USB_UNDEFINED 0x0100
|
||||
#define AUDIO_TERMINAL_USB_STREAMING 0x0101
|
||||
#define AUDIO_TERMINAL_USB_VENDOR_SPECIFIC 0x01FF
|
||||
|
||||
/* Input Terminal Types */
|
||||
#define AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200
|
||||
#define AUDIO_TERMINAL_MICROPHONE 0x0201
|
||||
#define AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202
|
||||
#define AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203
|
||||
#define AUDIO_TERMINAL_OMNI_DIR_MICROPHONE 0x0204
|
||||
#define AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205
|
||||
#define AUDIO_TERMINAL_PROCESSING_MIC_ARRAY 0x0206
|
||||
#define AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200
|
||||
#define AUDIO_TERMINAL_MICROPHONE 0x0201
|
||||
#define AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202
|
||||
#define AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203
|
||||
#define AUDIO_TERMINAL_OMNI_DIR_MICROPHONE 0x0204
|
||||
#define AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205
|
||||
#define AUDIO_TERMINAL_PROCESSING_MIC_ARRAY 0x0206
|
||||
|
||||
/* Output Terminal Types */
|
||||
#define AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300
|
||||
#define AUDIO_TERMINAL_SPEAKER 0x0301
|
||||
#define AUDIO_TERMINAL_HEADPHONES 0x0302
|
||||
#define AUDIO_TERMINAL_HEAD_MOUNTED_AUDIO 0x0303
|
||||
#define AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304
|
||||
#define AUDIO_TERMINAL_ROOM_SPEAKER 0x0305
|
||||
#define AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306
|
||||
#define AUDIO_TERMINAL_LOW_FREQ_SPEAKER 0x0307
|
||||
#define AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300
|
||||
#define AUDIO_TERMINAL_SPEAKER 0x0301
|
||||
#define AUDIO_TERMINAL_HEADPHONES 0x0302
|
||||
#define AUDIO_TERMINAL_HEAD_MOUNTED_AUDIO 0x0303
|
||||
#define AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304
|
||||
#define AUDIO_TERMINAL_ROOM_SPEAKER 0x0305
|
||||
#define AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306
|
||||
#define AUDIO_TERMINAL_LOW_FREQ_SPEAKER 0x0307
|
||||
|
||||
/* Bi-directional Terminal Types */
|
||||
#define AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400
|
||||
#define AUDIO_TERMINAL_HANDSET 0x0401
|
||||
#define AUDIO_TERMINAL_HEAD_MOUNTED_HANDSET 0x0402
|
||||
#define AUDIO_TERMINAL_SPEAKERPHONE 0x0403
|
||||
#define AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400
|
||||
#define AUDIO_TERMINAL_HANDSET 0x0401
|
||||
#define AUDIO_TERMINAL_HEAD_MOUNTED_HANDSET 0x0402
|
||||
#define AUDIO_TERMINAL_SPEAKERPHONE 0x0403
|
||||
#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOSUPRESS 0x0404
|
||||
#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOCANCEL 0x0405
|
||||
#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOCANCEL 0x0405
|
||||
|
||||
/* Telephony Terminal Types */
|
||||
#define AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500
|
||||
#define AUDIO_TERMINAL_PHONE_LINE 0x0501
|
||||
#define AUDIO_TERMINAL_TELEPHONE 0x0502
|
||||
#define AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503
|
||||
#define AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500
|
||||
#define AUDIO_TERMINAL_PHONE_LINE 0x0501
|
||||
#define AUDIO_TERMINAL_TELEPHONE 0x0502
|
||||
#define AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503
|
||||
|
||||
/* External Terminal Types */
|
||||
#define AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600
|
||||
#define AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601
|
||||
#define AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602
|
||||
#define AUDIO_TERMINAL_LINE_CONNECTOR 0x0603
|
||||
#define AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604
|
||||
#define AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605
|
||||
#define AUDIO_TERMINAL_1394_DA_STREAM 0x0606
|
||||
#define AUDIO_TERMINAL_1394_DA_STREAM_TRACK 0x0607
|
||||
#define AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600
|
||||
#define AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601
|
||||
#define AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602
|
||||
#define AUDIO_TERMINAL_LINE_CONNECTOR 0x0603
|
||||
#define AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604
|
||||
#define AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605
|
||||
#define AUDIO_TERMINAL_1394_DA_STREAM 0x0606
|
||||
#define AUDIO_TERMINAL_1394_DA_STREAM_TRACK 0x0607
|
||||
|
||||
/* Embedded Function Terminal Types */
|
||||
#define AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700
|
||||
#define AUDIO_TERMINAL_CALIBRATION_NOISE 0x0701
|
||||
#define AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702
|
||||
#define AUDIO_TERMINAL_CD_PLAYER 0x0703
|
||||
#define AUDIO_TERMINAL_DAT 0x0704
|
||||
#define AUDIO_TERMINAL_DCC 0x0705
|
||||
#define AUDIO_TERMINAL_MINI_DISK 0x0706
|
||||
#define AUDIO_TERMINAL_ANALOG_TAPE 0x0707
|
||||
#define AUDIO_TERMINAL_PHONOGRAPH 0x0708
|
||||
#define AUDIO_TERMINAL_VCR_AUDIO 0x0709
|
||||
#define AUDIO_TERMINAL_VIDEO_DISC_AUDIO 0x070A
|
||||
#define AUDIO_TERMINAL_DVD_AUDIO 0x070B
|
||||
#define AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C
|
||||
#define AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700
|
||||
#define AUDIO_TERMINAL_CALIBRATION_NOISE 0x0701
|
||||
#define AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702
|
||||
#define AUDIO_TERMINAL_CD_PLAYER 0x0703
|
||||
#define AUDIO_TERMINAL_DAT 0x0704
|
||||
#define AUDIO_TERMINAL_DCC 0x0705
|
||||
#define AUDIO_TERMINAL_MINI_DISK 0x0706
|
||||
#define AUDIO_TERMINAL_ANALOG_TAPE 0x0707
|
||||
#define AUDIO_TERMINAL_PHONOGRAPH 0x0708
|
||||
#define AUDIO_TERMINAL_VCR_AUDIO 0x0709
|
||||
#define AUDIO_TERMINAL_VIDEO_DISC_AUDIO 0x070A
|
||||
#define AUDIO_TERMINAL_DVD_AUDIO 0x070B
|
||||
#define AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C
|
||||
#define AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D
|
||||
#define AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E
|
||||
#define AUDIO_TERMINAL_DSS_AUDIO 0x070F
|
||||
#define AUDIO_TERMINAL_RADIO_RECEIVER 0x0710
|
||||
#define AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711
|
||||
#define AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712
|
||||
#define AUDIO_TERMINAL_SYNTHESIZER 0x0713
|
||||
#define AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E
|
||||
#define AUDIO_TERMINAL_DSS_AUDIO 0x070F
|
||||
#define AUDIO_TERMINAL_RADIO_RECEIVER 0x0710
|
||||
#define AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711
|
||||
#define AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712
|
||||
#define AUDIO_TERMINAL_SYNTHESIZER 0x0713
|
||||
|
||||
|
||||
#endif /* __AUDIO_H__ */
|
||||
#endif /* __AUDIO_H__ */
|
||||
|
|
|
@ -16,66 +16,73 @@
|
|||
#pragma once
|
||||
#include "audiodeviceproxy.h"
|
||||
|
||||
namespace usb_mic { namespace audiodev_noop {
|
||||
|
||||
static const char *APINAME = "noop";
|
||||
|
||||
class NoopAudioDevice : public AudioDevice
|
||||
namespace usb_mic
|
||||
{
|
||||
public:
|
||||
NoopAudioDevice(int port, const char* dev_type, int mic, AudioDir dir): AudioDevice(port, dev_type, mic, dir) {}
|
||||
~NoopAudioDevice() {}
|
||||
void Start() {}
|
||||
void Stop() {}
|
||||
virtual bool GetFrames(uint32_t *size)
|
||||
namespace audiodev_noop
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual uint32_t GetBuffer(int16_t *outBuf, uint32_t outFrames)
|
||||
{
|
||||
return outFrames;
|
||||
}
|
||||
virtual uint32_t SetBuffer(int16_t *inBuf, uint32_t inFrames)
|
||||
{
|
||||
return inFrames;
|
||||
}
|
||||
virtual void SetResampling(int samplerate) {}
|
||||
virtual uint32_t GetChannels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual bool Compare(AudioDevice* compare)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static const char* APINAME = "noop";
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("NOOP");
|
||||
}
|
||||
class NoopAudioDevice : public AudioDevice
|
||||
{
|
||||
public:
|
||||
NoopAudioDevice(int port, const char* dev_type, int mic, AudioDir dir)
|
||||
: AudioDevice(port, dev_type, mic, dir)
|
||||
{
|
||||
}
|
||||
~NoopAudioDevice() {}
|
||||
void Start() {}
|
||||
void Stop() {}
|
||||
virtual bool GetFrames(uint32_t* size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual uint32_t GetBuffer(int16_t* outBuf, uint32_t outFrames)
|
||||
{
|
||||
return outFrames;
|
||||
}
|
||||
virtual uint32_t SetBuffer(int16_t* inBuf, uint32_t inFrames)
|
||||
{
|
||||
return inFrames;
|
||||
}
|
||||
virtual void SetResampling(int samplerate) {}
|
||||
virtual uint32_t GetChannels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool AudioInit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool Compare(AudioDevice* compare)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void AudioDeinit()
|
||||
{
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("NOOP");
|
||||
}
|
||||
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo> &devices, AudioDir )
|
||||
{
|
||||
AudioDeviceInfo info;
|
||||
info.strID = TEXT("silence");
|
||||
info.strName = TEXT("Silence");
|
||||
devices.push_back(info);
|
||||
}
|
||||
static bool AudioInit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void *data)
|
||||
{
|
||||
return RESULT_OK;
|
||||
}
|
||||
};
|
||||
static void AudioDeinit()
|
||||
{
|
||||
}
|
||||
|
||||
}}
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo>& devices, AudioDir)
|
||||
{
|
||||
AudioDeviceInfo info;
|
||||
info.strID = TEXT("silence");
|
||||
info.strName = TEXT("Silence");
|
||||
devices.push_back(info);
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
return RESULT_OK;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace audiodev_noop
|
||||
} // namespace usb_mic
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,140 +25,145 @@
|
|||
#include <mutex>
|
||||
#include <chrono>
|
||||
|
||||
namespace usb_mic { namespace audiodev_pulse {
|
||||
namespace usb_mic
|
||||
{
|
||||
namespace audiodev_pulse
|
||||
{
|
||||
|
||||
// macros for string concat
|
||||
#undef APINAME_
|
||||
#define APINAME_ "pulse"
|
||||
|
||||
static const char *APINAME = "pulse";
|
||||
static const char* APINAME = "pulse";
|
||||
|
||||
using hrc = std::chrono::high_resolution_clock;
|
||||
using ms = std::chrono::milliseconds;
|
||||
using us = std::chrono::microseconds;
|
||||
using ns = std::chrono::nanoseconds;
|
||||
using sec = std::chrono::seconds;
|
||||
using hrc = std::chrono::high_resolution_clock;
|
||||
using ms = std::chrono::milliseconds;
|
||||
using us = std::chrono::microseconds;
|
||||
using ns = std::chrono::nanoseconds;
|
||||
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)
|
||||
, mBuffering(50)
|
||||
, mPaused(true)
|
||||
, mQuit(false)
|
||||
, mPMainLoop(nullptr)
|
||||
, mPContext(nullptr)
|
||||
, mStream(nullptr)
|
||||
, mServer(nullptr)
|
||||
, mPAready(0)
|
||||
, mResampleRatio(1.0)
|
||||
, mTimeAdjust(1.0)
|
||||
, mSamplesPerSec(48000)
|
||||
, mResampler(nullptr)
|
||||
, mOutSamples(0)
|
||||
{
|
||||
int i = dir == AUDIODIR_SOURCE ? 0 : 2;
|
||||
const char* var_names[] = {
|
||||
N_AUDIO_SOURCE0,
|
||||
N_AUDIO_SOURCE1,
|
||||
N_AUDIO_SINK0,
|
||||
N_AUDIO_SINK1
|
||||
class PulseAudioDevice : public AudioDevice
|
||||
{
|
||||
public:
|
||||
PulseAudioDevice(int port, const char* dev_type, int device, AudioDir dir)
|
||||
: AudioDevice(port, dev_type, device, dir)
|
||||
, mBuffering(50)
|
||||
, mPaused(true)
|
||||
, mQuit(false)
|
||||
, mPMainLoop(nullptr)
|
||||
, mPContext(nullptr)
|
||||
, mStream(nullptr)
|
||||
, mServer(nullptr)
|
||||
, mPAready(0)
|
||||
, mResampleRatio(1.0)
|
||||
, mTimeAdjust(1.0)
|
||||
, mSamplesPerSec(48000)
|
||||
, mResampler(nullptr)
|
||||
, mOutSamples(0)
|
||||
{
|
||||
int i = dir == AUDIODIR_SOURCE ? 0 : 2;
|
||||
const char* var_names[] = {
|
||||
N_AUDIO_SOURCE0,
|
||||
N_AUDIO_SOURCE1,
|
||||
N_AUDIO_SINK0,
|
||||
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");
|
||||
|
||||
LoadSetting(mDevType, mPort, APINAME, (dir == AUDIODIR_SOURCE ? N_BUFFER_LEN_SRC : N_BUFFER_LEN_SINK), mBuffering);
|
||||
mBuffering = MIN(1000, MAX(1, mBuffering));
|
||||
|
||||
if (!AudioInit())
|
||||
throw AudioDeviceError(APINAME_ ": failed to bind pulseaudio library");
|
||||
|
||||
mSSpec.format = PA_SAMPLE_FLOAT32LE; //PA_SAMPLE_S16LE;
|
||||
mSSpec.channels = 2;
|
||||
mSSpec.rate = 48000;
|
||||
|
||||
if (!Init())
|
||||
throw AudioDeviceError(APINAME_ ": failed to init");
|
||||
}
|
||||
|
||||
~PulseAudioDevice()
|
||||
{
|
||||
mQuit = true;
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
Uninit();
|
||||
AudioDeinit();
|
||||
mResampler = src_delete(mResampler);
|
||||
if (file)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
uint32_t GetBuffer(short* buff, uint32_t frames);
|
||||
uint32_t SetBuffer(short* buff, uint32_t frames);
|
||||
bool GetFrames(uint32_t* size);
|
||||
void SetResampling(int samplerate);
|
||||
void Start();
|
||||
void Stop();
|
||||
virtual bool Compare(AudioDevice* compare);
|
||||
void Uninit();
|
||||
bool Init();
|
||||
void ResetBuffers();
|
||||
|
||||
inline uint32_t GetChannels()
|
||||
{
|
||||
return mSSpec.channels;
|
||||
}
|
||||
|
||||
static const char* TypeName()
|
||||
{
|
||||
return APINAME;
|
||||
}
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return "PulseAudio";
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void* data);
|
||||
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo>& devices, AudioDir& dir);
|
||||
|
||||
static bool AudioInit();
|
||||
static void AudioDeinit();
|
||||
|
||||
static void context_state_cb(pa_context* c, void* userdata);
|
||||
static void stream_state_cb(pa_stream* s, void* userdata);
|
||||
static void stream_read_cb(pa_stream* p, size_t nbytes, void* userdata);
|
||||
static void stream_write_cb(pa_stream* p, size_t nbytes, void* userdata);
|
||||
static void stream_success_cb(pa_stream* p, int success, void* userdata) {}
|
||||
|
||||
protected:
|
||||
int mChannels;
|
||||
int mBuffering;
|
||||
std::string mDeviceName;
|
||||
int mSamplesPerSec;
|
||||
pa_sample_spec mSSpec;
|
||||
|
||||
SRC_STATE* mResampler;
|
||||
double mResampleRatio;
|
||||
// Speed up or slow down audio
|
||||
double mTimeAdjust;
|
||||
RingBuffer mOutBuffer;
|
||||
RingBuffer mInBuffer;
|
||||
//std::thread mThread;
|
||||
//std::condition_variable mEvent;
|
||||
std::mutex mMutex;
|
||||
bool mQuit;
|
||||
bool mPaused;
|
||||
hrc::time_point mLastGetBuffer;
|
||||
|
||||
int mPAready;
|
||||
pa_threaded_mainloop* mPMainLoop;
|
||||
pa_context* mPContext;
|
||||
pa_stream* mStream;
|
||||
char* mServer; //TODO add server selector?
|
||||
|
||||
int mOutSamples;
|
||||
hrc::time_point mLastOut;
|
||||
FILE* file = nullptr;
|
||||
};
|
||||
|
||||
if (!LoadSetting(mDevType, mPort, APINAME, (device ? var_names[i + 1] : var_names[i]), mDeviceName) || mDeviceName.empty())
|
||||
throw AudioDeviceError(APINAME_ ": failed to load device settings");
|
||||
|
||||
LoadSetting(mDevType, mPort, APINAME, (dir == AUDIODIR_SOURCE ? N_BUFFER_LEN_SRC : N_BUFFER_LEN_SINK), mBuffering);
|
||||
mBuffering = MIN(1000, MAX(1, mBuffering));
|
||||
|
||||
if (!AudioInit())
|
||||
throw AudioDeviceError(APINAME_ ": failed to bind pulseaudio library");
|
||||
|
||||
mSSpec.format = PA_SAMPLE_FLOAT32LE; //PA_SAMPLE_S16LE;
|
||||
mSSpec.channels = 2;
|
||||
mSSpec.rate = 48000;
|
||||
|
||||
if (!Init())
|
||||
throw AudioDeviceError(APINAME_ ": failed to init");
|
||||
}
|
||||
|
||||
~PulseAudioDevice()
|
||||
{
|
||||
mQuit = true;
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
Uninit();
|
||||
AudioDeinit();
|
||||
mResampler = src_delete(mResampler);
|
||||
if (file) fclose(file);
|
||||
}
|
||||
|
||||
uint32_t GetBuffer(short *buff, uint32_t frames);
|
||||
uint32_t SetBuffer(short *buff, uint32_t frames);
|
||||
bool GetFrames(uint32_t *size);
|
||||
void SetResampling(int samplerate);
|
||||
void Start();
|
||||
void Stop();
|
||||
virtual bool Compare(AudioDevice* compare);
|
||||
void Uninit();
|
||||
bool Init();
|
||||
void ResetBuffers();
|
||||
|
||||
inline uint32_t GetChannels()
|
||||
{
|
||||
return mSSpec.channels;
|
||||
}
|
||||
|
||||
static const char* TypeName()
|
||||
{
|
||||
return APINAME;
|
||||
}
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return "PulseAudio";
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void *data);
|
||||
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo> &devices, AudioDir& dir);
|
||||
|
||||
static bool AudioInit();
|
||||
static void AudioDeinit();
|
||||
|
||||
static void context_state_cb(pa_context *c, void *userdata);
|
||||
static void stream_state_cb(pa_stream *s, void *userdata);
|
||||
static void stream_read_cb (pa_stream *p, size_t nbytes, void *userdata);
|
||||
static void stream_write_cb (pa_stream *p, size_t nbytes, void *userdata);
|
||||
static void stream_success_cb (pa_stream *p, int success, void *userdata) {}
|
||||
|
||||
protected:
|
||||
int mChannels;
|
||||
int mBuffering;
|
||||
std::string mDeviceName;
|
||||
int mSamplesPerSec;
|
||||
pa_sample_spec mSSpec;
|
||||
|
||||
SRC_STATE *mResampler;
|
||||
double mResampleRatio;
|
||||
// Speed up or slow down audio
|
||||
double mTimeAdjust;
|
||||
RingBuffer mOutBuffer;
|
||||
RingBuffer mInBuffer;
|
||||
//std::thread mThread;
|
||||
//std::condition_variable mEvent;
|
||||
std::mutex mMutex;
|
||||
bool mQuit;
|
||||
bool mPaused;
|
||||
hrc::time_point mLastGetBuffer;
|
||||
|
||||
int mPAready;
|
||||
pa_threaded_mainloop *mPMainLoop;
|
||||
pa_context *mPContext;
|
||||
pa_stream *mStream;
|
||||
char *mServer; //TODO add server selector?
|
||||
|
||||
int mOutSamples;
|
||||
hrc::time_point mLastOut;
|
||||
FILE* file = nullptr;
|
||||
};
|
||||
}}
|
||||
} // namespace audiodev_pulse
|
||||
} // namespace usb_mic
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,135 +22,140 @@
|
|||
#include <mmdeviceapi.h>
|
||||
#include <audioclient.h>
|
||||
|
||||
namespace usb_mic { namespace audiodev_wasapi {
|
||||
|
||||
static const char *APINAME = "wasapi";
|
||||
|
||||
class MMAudioDevice : public AudioDevice
|
||||
namespace usb_mic
|
||||
{
|
||||
public:
|
||||
MMAudioDevice(int port, const char* dev_type, int device, AudioDir dir): AudioDevice(port, dev_type, device, dir)
|
||||
, mmCapture(NULL)
|
||||
, mmRender(NULL)
|
||||
, mmClient(NULL)
|
||||
, mmDevice(NULL)
|
||||
, mmClock(NULL)
|
||||
, mmEnumerator(NULL)
|
||||
, mResampler(NULL)
|
||||
, mDeviceLost(false)
|
||||
, mResample(false)
|
||||
, mFirstSamples(true)
|
||||
, mSamplesPerSec(48000)
|
||||
, mResampleRatio(1.0)
|
||||
, mTimeAdjust(1.0)
|
||||
, mThread(INVALID_HANDLE_VALUE)
|
||||
, mQuit(false)
|
||||
, mPaused(true)
|
||||
, mLastGetBufferMS(0)
|
||||
, mBuffering(50)
|
||||
namespace audiodev_wasapi
|
||||
{
|
||||
mMutex = CreateMutex(NULL, FALSE, TEXT("ResampledQueueMutex"));
|
||||
if(!Init())
|
||||
throw AudioDeviceError("MMAudioDevice:: device name is empty, skipping");
|
||||
if(!Reinitialize())
|
||||
throw AudioDeviceError("MMAudioDevice:: WASAPI init failed!");
|
||||
}
|
||||
|
||||
~MMAudioDevice();
|
||||
void FreeData();
|
||||
bool Init();
|
||||
bool Reinitialize();
|
||||
void Start();
|
||||
void Stop();
|
||||
void ResetBuffers();
|
||||
//TODO or just return samples count in mOutBuffer?
|
||||
virtual bool GetFrames(uint32_t *size);
|
||||
static const char* APINAME = "wasapi";
|
||||
|
||||
static unsigned WINAPI CaptureThread(LPVOID ptr);
|
||||
static unsigned WINAPI RenderThread(LPVOID ptr);
|
||||
class MMAudioDevice : public AudioDevice
|
||||
{
|
||||
public:
|
||||
MMAudioDevice(int port, const char* dev_type, int device, AudioDir dir)
|
||||
: AudioDevice(port, dev_type, device, dir)
|
||||
, mmCapture(NULL)
|
||||
, mmRender(NULL)
|
||||
, mmClient(NULL)
|
||||
, mmDevice(NULL)
|
||||
, mmClock(NULL)
|
||||
, mmEnumerator(NULL)
|
||||
, mResampler(NULL)
|
||||
, mDeviceLost(false)
|
||||
, mResample(false)
|
||||
, mFirstSamples(true)
|
||||
, mSamplesPerSec(48000)
|
||||
, mResampleRatio(1.0)
|
||||
, mTimeAdjust(1.0)
|
||||
, mThread(INVALID_HANDLE_VALUE)
|
||||
, mQuit(false)
|
||||
, mPaused(true)
|
||||
, mLastGetBufferMS(0)
|
||||
, mBuffering(50)
|
||||
{
|
||||
mMutex = CreateMutex(NULL, FALSE, TEXT("ResampledQueueMutex"));
|
||||
if (!Init())
|
||||
throw AudioDeviceError("MMAudioDevice:: device name is empty, skipping");
|
||||
if (!Reinitialize())
|
||||
throw AudioDeviceError("MMAudioDevice:: WASAPI init failed!");
|
||||
}
|
||||
|
||||
virtual uint32_t GetBuffer(int16_t *outBuf, uint32_t outFrames);
|
||||
virtual uint32_t SetBuffer(int16_t *inBuf, uint32_t inFrames);
|
||||
/*
|
||||
~MMAudioDevice();
|
||||
void FreeData();
|
||||
bool Init();
|
||||
bool Reinitialize();
|
||||
void Start();
|
||||
void Stop();
|
||||
void ResetBuffers();
|
||||
//TODO or just return samples count in mOutBuffer?
|
||||
virtual bool GetFrames(uint32_t* size);
|
||||
|
||||
static unsigned WINAPI CaptureThread(LPVOID ptr);
|
||||
static unsigned WINAPI RenderThread(LPVOID ptr);
|
||||
|
||||
virtual uint32_t GetBuffer(int16_t* outBuf, uint32_t outFrames);
|
||||
virtual uint32_t SetBuffer(int16_t* inBuf, uint32_t inFrames);
|
||||
/*
|
||||
Returns read frame count.
|
||||
*/
|
||||
uint32_t GetMMBuffer();
|
||||
virtual void SetResampling(int samplerate);
|
||||
virtual uint32_t GetChannels()
|
||||
{
|
||||
return mDeviceChannels;
|
||||
}
|
||||
uint32_t GetMMBuffer();
|
||||
virtual void SetResampling(int samplerate);
|
||||
virtual uint32_t GetChannels()
|
||||
{
|
||||
return mDeviceChannels;
|
||||
}
|
||||
|
||||
virtual bool Compare(AudioDevice* compare)
|
||||
{
|
||||
if (compare)
|
||||
{
|
||||
MMAudioDevice *src = static_cast<MMAudioDevice *>(compare);
|
||||
if (src && mDevID == src->mDevID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool Compare(AudioDevice* compare)
|
||||
{
|
||||
if (compare)
|
||||
{
|
||||
MMAudioDevice* src = static_cast<MMAudioDevice*>(compare);
|
||||
if (src && mDevID == src->mDevID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char* TypeName()
|
||||
{
|
||||
return APINAME;
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return APINAME;
|
||||
}
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("WASAPI");
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("WASAPI");
|
||||
}
|
||||
|
||||
static bool AudioInit();
|
||||
static bool AudioInit();
|
||||
|
||||
static void AudioDeinit()
|
||||
{
|
||||
}
|
||||
static void AudioDeinit()
|
||||
{
|
||||
}
|
||||
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo> &devices, AudioDir dir);
|
||||
static int Configure(int port, const char* dev_type, void *data);
|
||||
static void AudioDevices(std::vector<AudioDeviceInfo>& devices, AudioDir dir);
|
||||
static int Configure(int port, const char* dev_type, void* data);
|
||||
|
||||
private:
|
||||
IMMDeviceEnumerator *mmEnumerator;
|
||||
private:
|
||||
IMMDeviceEnumerator* mmEnumerator;
|
||||
|
||||
IMMDevice *mmDevice;
|
||||
IAudioClient *mmClient;
|
||||
IAudioCaptureClient *mmCapture;
|
||||
IAudioRenderClient *mmRender;
|
||||
IAudioClock *mmClock;
|
||||
IMMDevice* mmDevice;
|
||||
IAudioClient* mmClient;
|
||||
IAudioCaptureClient* mmCapture;
|
||||
IAudioRenderClient* mmRender;
|
||||
IAudioClock* mmClock;
|
||||
|
||||
bool mResample;
|
||||
bool mFloat;
|
||||
bool mFirstSamples; //On the first call, empty the buffer to lower latency
|
||||
UINT mDeviceChannels;
|
||||
UINT mDeviceSamplesPerSec;
|
||||
UINT mSamplesPerSec;
|
||||
UINT mDeviceBitsPerSample;
|
||||
UINT mDeviceBlockSize;
|
||||
DWORD mInputChannelMask;
|
||||
bool mResample;
|
||||
bool mFloat;
|
||||
bool mFirstSamples; //On the first call, empty the buffer to lower latency
|
||||
UINT mDeviceChannels;
|
||||
UINT mDeviceSamplesPerSec;
|
||||
UINT mSamplesPerSec;
|
||||
UINT mDeviceBitsPerSample;
|
||||
UINT mDeviceBlockSize;
|
||||
DWORD mInputChannelMask;
|
||||
|
||||
std::wstring mDevID;
|
||||
bool mDeviceLost;
|
||||
std::wstring mDeviceName;
|
||||
LONGLONG mBuffering;
|
||||
std::wstring mDevID;
|
||||
bool mDeviceLost;
|
||||
std::wstring mDeviceName;
|
||||
LONGLONG mBuffering;
|
||||
|
||||
SRC_STATE *mResampler;
|
||||
double mResampleRatio;
|
||||
// Speed up or slow down audio
|
||||
double mTimeAdjust;
|
||||
RingBuffer mInBuffer;
|
||||
RingBuffer mOutBuffer;
|
||||
HANDLE mThread;
|
||||
HANDLE mMutex;
|
||||
bool mQuit;
|
||||
bool mPaused;
|
||||
LONGLONG mLastGetBufferMS;
|
||||
SRC_STATE* mResampler;
|
||||
double mResampleRatio;
|
||||
// Speed up or slow down audio
|
||||
double mTimeAdjust;
|
||||
RingBuffer mInBuffer;
|
||||
RingBuffer mOutBuffer;
|
||||
HANDLE mThread;
|
||||
HANDLE mMutex;
|
||||
bool mQuit;
|
||||
bool mPaused;
|
||||
LONGLONG mLastGetBufferMS;
|
||||
|
||||
LONGLONG mTime = 0;
|
||||
int mSamples = 0;
|
||||
LONGLONG mLastTimeMS = 0;
|
||||
LONGLONG mLastTimeNS = 0;
|
||||
};
|
||||
LONGLONG mTime = 0;
|
||||
int mSamples = 0;
|
||||
LONGLONG mLastTimeMS = 0;
|
||||
LONGLONG mLastTimeNS = 0;
|
||||
};
|
||||
|
||||
}} // namespace
|
||||
} // namespace audiodev_wasapi
|
||||
} // namespace usb_mic
|
||||
|
|
|
@ -24,29 +24,31 @@
|
|||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#define S_AUDIO_SOURCE0 TEXT("Audio source 1")
|
||||
#define S_AUDIO_SOURCE1 TEXT("Audio source 2")
|
||||
#define S_AUDIO_SINK0 TEXT("Audio sink 1")
|
||||
#define S_AUDIO_SINK1 TEXT("Audio sink 2")
|
||||
#define N_AUDIO_SOURCE0 TEXT("audio_src_0")
|
||||
#define N_AUDIO_SOURCE1 TEXT("audio_src_1")
|
||||
#define N_AUDIO_SINK0 TEXT("audio_sink_0")
|
||||
#define N_AUDIO_SINK1 TEXT("audio_sink_1")
|
||||
#define S_BUFFER_LEN TEXT("Buffer length")
|
||||
#define N_BUFFER_LEN TEXT("buffer_len")
|
||||
#define N_BUFFER_LEN_SRC TEXT("buffer_len_src")
|
||||
#define N_BUFFER_LEN_SINK TEXT("buffer_len_sink")
|
||||
#define S_AUDIO_SOURCE0 TEXT("Audio source 1")
|
||||
#define S_AUDIO_SOURCE1 TEXT("Audio source 2")
|
||||
#define S_AUDIO_SINK0 TEXT("Audio sink 1")
|
||||
#define S_AUDIO_SINK1 TEXT("Audio sink 2")
|
||||
#define N_AUDIO_SOURCE0 TEXT("audio_src_0")
|
||||
#define N_AUDIO_SOURCE1 TEXT("audio_src_1")
|
||||
#define N_AUDIO_SINK0 TEXT("audio_sink_0")
|
||||
#define N_AUDIO_SINK1 TEXT("audio_sink_1")
|
||||
#define S_BUFFER_LEN TEXT("Buffer length")
|
||||
#define N_BUFFER_LEN TEXT("buffer_len")
|
||||
#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,
|
||||
// Use same source for both player or
|
||||
// left channel for P1 and right for P2 if stereo.
|
||||
// Use same source for both player or
|
||||
// left channel for P1 and right for P2 if stereo.
|
||||
MIC_MODE_SHARED
|
||||
};
|
||||
|
||||
enum AudioDir {
|
||||
enum AudioDir
|
||||
{
|
||||
AUDIODIR_SOURCE = 0,
|
||||
AUDIODIR_SINK
|
||||
};
|
||||
|
@ -75,28 +77,30 @@ struct AudioDeviceInfoW
|
|||
class AudioDevice
|
||||
{
|
||||
public:
|
||||
AudioDevice(int port, const char* dev_type, int device, AudioDir dir): mPort(port)
|
||||
, mDevType(dev_type)
|
||||
, mDevice(device)
|
||||
, mAudioDir(dir)
|
||||
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;
|
||||
const char* mDevType;
|
||||
int mDevice;
|
||||
AudioDir mAudioDir;
|
||||
|
||||
public:
|
||||
virtual ~AudioDevice() {}
|
||||
//get buffer, converted to 16bit int format
|
||||
virtual uint32_t GetBuffer(int16_t *buff, uint32_t len) = 0;
|
||||
virtual uint32_t SetBuffer(int16_t *buff, uint32_t len) = 0;
|
||||
virtual uint32_t GetBuffer(int16_t* buff, uint32_t len) = 0;
|
||||
virtual uint32_t SetBuffer(int16_t* buff, uint32_t len) = 0;
|
||||
/*
|
||||
Get how many frames has been recorded so that caller knows
|
||||
how much to allocated for 16-bit buffer.
|
||||
*/
|
||||
virtual bool GetFrames(uint32_t *size) = 0;
|
||||
virtual bool GetFrames(uint32_t* size) = 0;
|
||||
virtual void SetResampling(int samplerate) = 0;
|
||||
virtual uint32_t GetChannels() = 0;
|
||||
|
||||
|
|
|
@ -27,78 +27,85 @@
|
|||
#include "../osdebugout.h"
|
||||
#include "audiodev.h"
|
||||
|
||||
namespace usb_mic {
|
||||
|
||||
class AudioDeviceError : public std::runtime_error
|
||||
namespace usb_mic
|
||||
{
|
||||
public:
|
||||
AudioDeviceError(const char* msg) : std::runtime_error(msg) {}
|
||||
virtual ~AudioDeviceError() throw () {}
|
||||
};
|
||||
|
||||
class AudioDeviceProxyBase : public ProxyBase
|
||||
{
|
||||
AudioDeviceProxyBase(const AudioDeviceProxyBase&) = delete;
|
||||
AudioDeviceProxyBase& operator=(const AudioDeviceProxyBase&) = delete;
|
||||
|
||||
public:
|
||||
AudioDeviceProxyBase() {};
|
||||
AudioDeviceProxyBase(const std::string& name);
|
||||
virtual AudioDevice* CreateObject(int port, const char* dev_type, int mic, AudioDir dir) const = 0; //Can be generalized? Probably not
|
||||
virtual void AudioDevices(std::vector<AudioDeviceInfo> &devices, AudioDir) const = 0;
|
||||
virtual bool AudioInit() = 0;
|
||||
virtual void AudioDeinit() = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class AudioDeviceProxy : public AudioDeviceProxyBase
|
||||
{
|
||||
AudioDeviceProxy(const AudioDeviceProxy&) = delete;
|
||||
|
||||
public:
|
||||
AudioDeviceProxy() {}
|
||||
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
|
||||
class AudioDeviceError : public std::runtime_error
|
||||
{
|
||||
try
|
||||
public:
|
||||
AudioDeviceError(const char* msg)
|
||||
: std::runtime_error(msg)
|
||||
{
|
||||
return new T(port, dev_type, mic, dir);
|
||||
}
|
||||
catch(AudioDeviceError& err)
|
||||
{
|
||||
OSDebugOut(TEXT("AudioDevice port %d mic %d: %") TEXT(SFMTs) TEXT("\n"), port, mic, err.what());
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, void *data)
|
||||
{
|
||||
return T::Configure(port, dev_type, data);
|
||||
}
|
||||
virtual void AudioDevices(std::vector<AudioDeviceInfo> &devices, AudioDir dir) const
|
||||
{
|
||||
T::AudioDevices(devices, dir);
|
||||
}
|
||||
virtual bool AudioInit()
|
||||
{
|
||||
return T::AudioInit();
|
||||
}
|
||||
virtual void AudioDeinit()
|
||||
{
|
||||
T::AudioDeinit();
|
||||
}
|
||||
};
|
||||
virtual ~AudioDeviceError() throw() {}
|
||||
};
|
||||
|
||||
class AudioDeviceProxyBase : public ProxyBase
|
||||
{
|
||||
AudioDeviceProxyBase(const AudioDeviceProxyBase&) = delete;
|
||||
AudioDeviceProxyBase& operator=(const AudioDeviceProxyBase&) = delete;
|
||||
|
||||
class RegisterAudioDevice : public RegisterProxy<AudioDeviceProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
}
|
||||
AudioDeviceProxyBase(){};
|
||||
AudioDeviceProxyBase(const std::string& name);
|
||||
virtual AudioDevice* CreateObject(int port, const char* dev_type, int mic, AudioDir dir) const = 0; //Can be generalized? Probably not
|
||||
virtual void AudioDevices(std::vector<AudioDeviceInfo>& devices, AudioDir) const = 0;
|
||||
virtual bool AudioInit() = 0;
|
||||
virtual void AudioDeinit() = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class AudioDeviceProxy : public AudioDeviceProxyBase
|
||||
{
|
||||
AudioDeviceProxy(const AudioDeviceProxy&) = delete;
|
||||
|
||||
public:
|
||||
AudioDeviceProxy() {}
|
||||
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
|
||||
{
|
||||
try
|
||||
{
|
||||
return new T(port, dev_type, mic, dir);
|
||||
}
|
||||
catch (AudioDeviceError& err)
|
||||
{
|
||||
OSDebugOut(TEXT("AudioDevice port %d mic %d: %") TEXT(SFMTs) TEXT("\n"), port, mic, err.what());
|
||||
(void)err;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
virtual const TCHAR* Name() const
|
||||
{
|
||||
return T::Name();
|
||||
}
|
||||
virtual int Configure(int port, const char* dev_type, void* data)
|
||||
{
|
||||
return T::Configure(port, dev_type, data);
|
||||
}
|
||||
virtual void AudioDevices(std::vector<AudioDeviceInfo>& devices, AudioDir dir) const
|
||||
{
|
||||
T::AudioDevices(devices, dir);
|
||||
}
|
||||
virtual bool AudioInit()
|
||||
{
|
||||
return T::AudioInit();
|
||||
}
|
||||
virtual void AudioDeinit()
|
||||
{
|
||||
T::AudioDeinit();
|
||||
}
|
||||
};
|
||||
|
||||
class RegisterAudioDevice : public RegisterProxy<AudioDeviceProxyBase>
|
||||
{
|
||||
public:
|
||||
static void Register();
|
||||
};
|
||||
} // namespace usb_mic
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,26 +16,27 @@
|
|||
#include "../deviceproxy.h"
|
||||
#include "audiodeviceproxy.h"
|
||||
|
||||
namespace usb_mic {
|
||||
|
||||
class HeadsetDevice
|
||||
namespace usb_mic
|
||||
{
|
||||
public:
|
||||
virtual ~HeadsetDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static USBDevice* CreateDevice(int port, const std::string& api);
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "headset";
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Logitech USB Headset");
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
|
||||
}
|
||||
class HeadsetDevice
|
||||
{
|
||||
public:
|
||||
virtual ~HeadsetDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static USBDevice* CreateDevice(int port, const std::string& api);
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "headset";
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Logitech USB Headset");
|
||||
}
|
||||
static std::list<std::string> ListAPIs();
|
||||
static const TCHAR* LongAPIName(const std::string& name);
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
} // namespace usb_mic
|
||||
|
|
|
@ -17,257 +17,256 @@
|
|||
#include "audio.h"
|
||||
#include "../qemu-usb/desc.h"
|
||||
|
||||
namespace usb_mic {
|
||||
|
||||
static const uint8_t logitech_mic_dev_descriptor[] = {
|
||||
/* bLength */ 0x12, //(18)
|
||||
/* bDescriptorType */ 0x01, //(1)
|
||||
/* bcdUSB */ WBVAL(0x0110), //(272)
|
||||
/* bDeviceClass */ 0x00, //(0)
|
||||
/* bDeviceSubClass */ 0x00, //(0)
|
||||
/* bDeviceProtocol */ 0x00, //(0)
|
||||
/* bMaxPacketSize0 */ 0x08, //(8)
|
||||
/* idVendor */ WBVAL(0x046D),
|
||||
/* idProduct */ WBVAL(0x0000), //(0)
|
||||
/* bcdDevice */ WBVAL(0x0001), //(1)
|
||||
/* iManufacturer */ 0x01, //(1)
|
||||
/* iProduct */ 0x02, //(2)
|
||||
/* iSerialNumber */ 0x00, //(0) unused
|
||||
/* bNumConfigurations */ 0x01, //(1)
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t logitech_mic_config_descriptor[] = {
|
||||
|
||||
/* Configuration 1 */
|
||||
0x09, /* bLength */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL(0x00b1), /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
USB_CONFIG_BUS_POWERED, /* bmAttributes */
|
||||
USB_CONFIG_POWER_MA(90), /* bMaxPower */
|
||||
|
||||
/* Interface 0, Alternate Setting 0, Audio Control */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Control Interface */
|
||||
AUDIO_CONTROL_INTERFACE_DESC_SZ(1), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
|
||||
WBVAL(0x0100), /* 1.00 */ /* bcdADC */
|
||||
WBVAL(0x0028), /* wTotalLength */
|
||||
0x01, /* bInCollection */
|
||||
0x01, /* baInterfaceNr */
|
||||
|
||||
/* Audio Input Terminal */
|
||||
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x01, /* bTerminalID */
|
||||
WBVAL(AUDIO_TERMINAL_MICROPHONE), /* wTerminalType */
|
||||
0x02, /* bAssocTerminal */
|
||||
0x02, /* bNrChannels */
|
||||
WBVAL(AUDIO_CHANNEL_L
|
||||
| AUDIO_CHANNEL_R), /* wChannelConfig */
|
||||
0x00, /* iChannelNames */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Audio Output Terminal */
|
||||
AUDIO_OUTPUT_TERMINAL_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalID */
|
||||
WBVAL(AUDIO_TERMINAL_USB_STREAMING), /* wTerminalType */
|
||||
0x01, /* bAssocTerminal */
|
||||
0x03, /* bSourceID */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Audio Feature Unit */
|
||||
AUDIO_FEATURE_UNIT_DESC_SZ(2,1), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
|
||||
0x03, /* bUnitID */
|
||||
0x01, /* bSourceID */
|
||||
0x01, /* bControlSize */
|
||||
0x01, /* bmaControls(0) */
|
||||
0x02, /* bmaControls(1) */
|
||||
0x02, /* bmaControls(2) */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Streaming Interface */
|
||||
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalLink */
|
||||
0x01, /* bDelay */
|
||||
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */
|
||||
|
||||
/* Audio Type I Format */
|
||||
AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */
|
||||
0x01, /* bNrChannels */
|
||||
0x02, /* bSubFrameSize */
|
||||
0x10, /* bBitResolution */
|
||||
0x05, /* bSamFreqType */
|
||||
B3VAL(8000), /* tSamFreq 1 */
|
||||
B3VAL(11025), /* tSamFreq 2 */
|
||||
B3VAL(22050), /* tSamFreq 3 */
|
||||
B3VAL(44100), /* tSamFreq 4 */
|
||||
B3VAL(48000), /* tSamFreq 5 */
|
||||
|
||||
/* Endpoint - Standard 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 */
|
||||
WBVAL(0x0064), /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
0x00, /* bRefresh */
|
||||
0x00, /* bSynchAddress */
|
||||
|
||||
/* Endpoint - Audio Streaming */
|
||||
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
|
||||
0x01, /* bmAttributes */
|
||||
0x00, /* bLockDelayUnits */
|
||||
WBVAL(0x0000), /* wLockDelay */
|
||||
|
||||
/* Interface 1, Alternate Setting 2, Audio Streaming - ? */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x02, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Streaming Interface */
|
||||
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalLink */
|
||||
0x01, /* bDelay */
|
||||
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */
|
||||
|
||||
/* Audio Type I Format */
|
||||
AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */
|
||||
0x02, /* bNrChannels */
|
||||
0x02, /* bSubFrameSize */
|
||||
0x10, /* bBitResolution */
|
||||
0x05, /* bSamFreqType */
|
||||
B3VAL(8000), /* tSamFreq 1 */
|
||||
B3VAL(11025), /* tSamFreq 2 */
|
||||
B3VAL(22050), /* tSamFreq 3 */
|
||||
B3VAL(44100), /* tSamFreq 4 */
|
||||
B3VAL(48000), /* tSamFreq 5 */
|
||||
|
||||
/* Endpoint - Standard 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 */
|
||||
WBVAL(0x00c8), /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
0x00, /* bRefresh */
|
||||
0x00, /* bSynchAddress */
|
||||
|
||||
/* Endpoint - Audio Streaming */
|
||||
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
|
||||
0x01, /* bmAttributes */
|
||||
0x00, /* bLockDelayUnits */
|
||||
WBVAL(0x0000), /* wLockDelay */
|
||||
|
||||
/* Terminator */
|
||||
0 /* bLength */
|
||||
};
|
||||
|
||||
static const USBDescStrings lt_desc_strings = {
|
||||
"",
|
||||
"Logitech",
|
||||
"USBMIC",
|
||||
};
|
||||
|
||||
//Minified state
|
||||
typedef struct SINGSTARMICMINIState {
|
||||
USBDevice dev;
|
||||
|
||||
USBDesc desc;
|
||||
USBDescDevice desc_dev;
|
||||
} SINGSTARMICMINIState;
|
||||
|
||||
USBDevice* LogitechMicDevice::CreateDevice(int port)
|
||||
namespace usb_mic
|
||||
{
|
||||
std::string api;
|
||||
if (!LoadSetting(nullptr, port, TypeName(), N_DEVICE_API, api))
|
||||
|
||||
static const uint8_t logitech_mic_dev_descriptor[] = {
|
||||
/* bLength */ 0x12, //(18)
|
||||
/* bDescriptorType */ 0x01, //(1)
|
||||
/* bcdUSB */ WBVAL(0x0110), //(272)
|
||||
/* bDeviceClass */ 0x00, //(0)
|
||||
/* bDeviceSubClass */ 0x00, //(0)
|
||||
/* bDeviceProtocol */ 0x00, //(0)
|
||||
/* bMaxPacketSize0 */ 0x08, //(8)
|
||||
/* idVendor */ WBVAL(0x046D),
|
||||
/* idProduct */ WBVAL(0x0000), //(0)
|
||||
/* bcdDevice */ WBVAL(0x0001), //(1)
|
||||
/* iManufacturer */ 0x01, //(1)
|
||||
/* iProduct */ 0x02, //(2)
|
||||
/* iSerialNumber */ 0x00, //(0) unused
|
||||
/* bNumConfigurations */ 0x01, //(1)
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t logitech_mic_config_descriptor[] = {
|
||||
|
||||
/* Configuration 1 */
|
||||
0x09, /* bLength */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL(0x00b1), /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
USB_CONFIG_BUS_POWERED, /* bmAttributes */
|
||||
USB_CONFIG_POWER_MA(90), /* bMaxPower */
|
||||
|
||||
/* Interface 0, Alternate Setting 0, Audio Control */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Control Interface */
|
||||
AUDIO_CONTROL_INTERFACE_DESC_SZ(1), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
|
||||
WBVAL(0x0100), /* 1.00 */ /* bcdADC */
|
||||
WBVAL(0x0028), /* wTotalLength */
|
||||
0x01, /* bInCollection */
|
||||
0x01, /* baInterfaceNr */
|
||||
|
||||
/* Audio Input Terminal */
|
||||
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x01, /* bTerminalID */
|
||||
WBVAL(AUDIO_TERMINAL_MICROPHONE), /* wTerminalType */
|
||||
0x02, /* bAssocTerminal */
|
||||
0x02, /* bNrChannels */
|
||||
WBVAL(AUDIO_CHANNEL_L | AUDIO_CHANNEL_R), /* wChannelConfig */
|
||||
0x00, /* iChannelNames */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Audio Output Terminal */
|
||||
AUDIO_OUTPUT_TERMINAL_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalID */
|
||||
WBVAL(AUDIO_TERMINAL_USB_STREAMING), /* wTerminalType */
|
||||
0x01, /* bAssocTerminal */
|
||||
0x03, /* bSourceID */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Audio Feature Unit */
|
||||
AUDIO_FEATURE_UNIT_DESC_SZ(2, 1), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
|
||||
0x03, /* bUnitID */
|
||||
0x01, /* bSourceID */
|
||||
0x01, /* bControlSize */
|
||||
0x01, /* bmaControls(0) */
|
||||
0x02, /* bmaControls(1) */
|
||||
0x02, /* bmaControls(2) */
|
||||
0x00, /* iTerminal */
|
||||
|
||||
/* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Streaming Interface */
|
||||
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalLink */
|
||||
0x01, /* bDelay */
|
||||
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */
|
||||
|
||||
/* Audio Type I Format */
|
||||
AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */
|
||||
0x01, /* bNrChannels */
|
||||
0x02, /* bSubFrameSize */
|
||||
0x10, /* bBitResolution */
|
||||
0x05, /* bSamFreqType */
|
||||
B3VAL(8000), /* tSamFreq 1 */
|
||||
B3VAL(11025), /* tSamFreq 2 */
|
||||
B3VAL(22050), /* tSamFreq 3 */
|
||||
B3VAL(44100), /* tSamFreq 4 */
|
||||
B3VAL(48000), /* tSamFreq 5 */
|
||||
|
||||
/* Endpoint - Standard 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 */
|
||||
WBVAL(0x0064), /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
0x00, /* bRefresh */
|
||||
0x00, /* bSynchAddress */
|
||||
|
||||
/* Endpoint - Audio Streaming */
|
||||
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
|
||||
0x01, /* bmAttributes */
|
||||
0x00, /* bLockDelayUnits */
|
||||
WBVAL(0x0000), /* wLockDelay */
|
||||
|
||||
/* Interface 1, Alternate Setting 2, Audio Streaming - ? */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x02, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
USB_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Audio Streaming Interface */
|
||||
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
|
||||
0x02, /* bTerminalLink */
|
||||
0x01, /* bDelay */
|
||||
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */
|
||||
|
||||
/* Audio Type I Format */
|
||||
AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */
|
||||
0x02, /* bNrChannels */
|
||||
0x02, /* bSubFrameSize */
|
||||
0x10, /* bBitResolution */
|
||||
0x05, /* bSamFreqType */
|
||||
B3VAL(8000), /* tSamFreq 1 */
|
||||
B3VAL(11025), /* tSamFreq 2 */
|
||||
B3VAL(22050), /* tSamFreq 3 */
|
||||
B3VAL(44100), /* tSamFreq 4 */
|
||||
B3VAL(48000), /* tSamFreq 5 */
|
||||
|
||||
/* Endpoint - Standard 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 */
|
||||
WBVAL(0x00c8), /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
0x00, /* bRefresh */
|
||||
0x00, /* bSynchAddress */
|
||||
|
||||
/* Endpoint - Audio Streaming */
|
||||
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
|
||||
0x01, /* bmAttributes */
|
||||
0x00, /* bLockDelayUnits */
|
||||
WBVAL(0x0000), /* wLockDelay */
|
||||
|
||||
/* Terminator */
|
||||
0 /* bLength */
|
||||
};
|
||||
|
||||
static const USBDescStrings lt_desc_strings = {
|
||||
"",
|
||||
"Logitech",
|
||||
"USBMIC",
|
||||
};
|
||||
|
||||
//Minified state
|
||||
typedef struct SINGSTARMICMINIState
|
||||
{
|
||||
USBDevice dev;
|
||||
|
||||
USBDesc desc;
|
||||
USBDescDevice desc_dev;
|
||||
} SINGSTARMICMINIState;
|
||||
|
||||
USBDevice* LogitechMicDevice::CreateDevice(int port)
|
||||
{
|
||||
std::string api;
|
||||
if (!LoadSetting(nullptr, port, TypeName(), N_DEVICE_API, api))
|
||||
return nullptr;
|
||||
|
||||
USBDevice* dev = SingstarDevice::CreateDevice(port, api);
|
||||
if (!dev)
|
||||
return nullptr;
|
||||
|
||||
SINGSTARMICMINIState* s = (SINGSTARMICMINIState*)dev;
|
||||
s->desc = {};
|
||||
s->desc_dev = {};
|
||||
|
||||
s->desc.str = lt_desc_strings;
|
||||
s->desc.full = &s->desc_dev;
|
||||
|
||||
if (usb_desc_parse_dev(logitech_mic_dev_descriptor, sizeof(logitech_mic_dev_descriptor), s->desc, s->desc_dev) < 0)
|
||||
goto fail;
|
||||
if (usb_desc_parse_config(logitech_mic_config_descriptor, sizeof(logitech_mic_config_descriptor), s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = lt_desc_strings[2];
|
||||
usb_desc_init(&s->dev);
|
||||
return dev;
|
||||
fail:
|
||||
s->dev.klass.unrealize(dev);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
USBDevice* dev = SingstarDevice::CreateDevice(port, api);
|
||||
if (!dev)
|
||||
return nullptr;
|
||||
|
||||
SINGSTARMICMINIState *s = (SINGSTARMICMINIState *)dev;
|
||||
s->desc = {};
|
||||
s->desc_dev = {};
|
||||
|
||||
s->desc.str = lt_desc_strings;
|
||||
s->desc.full = &s->desc_dev;
|
||||
|
||||
if (usb_desc_parse_dev (logitech_mic_dev_descriptor, sizeof(logitech_mic_dev_descriptor), s->desc, s->desc_dev) < 0)
|
||||
goto fail;
|
||||
if (usb_desc_parse_config (logitech_mic_config_descriptor, sizeof(logitech_mic_config_descriptor), s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = lt_desc_strings[2];
|
||||
usb_desc_init(&s->dev);
|
||||
return dev;
|
||||
fail:
|
||||
s->dev.klass.unrealize (dev);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace usb_mic
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,50 +20,51 @@
|
|||
|
||||
struct USBDevice;
|
||||
|
||||
namespace usb_mic {
|
||||
class SingstarDevice
|
||||
namespace usb_mic
|
||||
{
|
||||
public:
|
||||
virtual ~SingstarDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static USBDevice* CreateDevice(int port, const std::string& api);
|
||||
static const TCHAR* Name()
|
||||
class SingstarDevice
|
||||
{
|
||||
return TEXT("Singstar");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "singstar";
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return RegisterAudioDevice::instance().Names();
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
auto proxy = RegisterAudioDevice::instance().Proxy(name);
|
||||
if (proxy)
|
||||
return proxy->Name();
|
||||
return nullptr;
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
public:
|
||||
virtual ~SingstarDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static USBDevice* CreateDevice(int port, const std::string& api);
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Singstar");
|
||||
}
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "singstar";
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return RegisterAudioDevice::instance().Names();
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
auto proxy = RegisterAudioDevice::instance().Proxy(name);
|
||||
if (proxy)
|
||||
return proxy->Name();
|
||||
return nullptr;
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
class LogitechMicDevice : public SingstarDevice
|
||||
{
|
||||
public:
|
||||
virtual ~LogitechMicDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const char* TypeName()
|
||||
class LogitechMicDevice : public SingstarDevice
|
||||
{
|
||||
return "logitech_usbmic";
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Logitech USB Mic");
|
||||
}
|
||||
};
|
||||
public:
|
||||
virtual ~LogitechMicDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const char* TypeName()
|
||||
{
|
||||
return "logitech_usbmic";
|
||||
}
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Logitech USB Mic");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace usb_mic
|
||||
#endif
|
||||
|
|
|
@ -18,104 +18,105 @@
|
|||
#include "../configuration.h"
|
||||
#include "../gtk.h"
|
||||
|
||||
namespace usb_msd {
|
||||
|
||||
static void entryChanged(GtkWidget *widget, gpointer data)
|
||||
namespace usb_msd
|
||||
{
|
||||
const gchar *text = gtk_entry_get_text(GTK_ENTRY(widget));
|
||||
//fprintf(stderr, "Entry text:%s\n", text);
|
||||
}
|
||||
|
||||
static void fileChooser( GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget *dialog, *entry = NULL;
|
||||
|
||||
entry = (GtkWidget*)data;
|
||||
dialog = gtk_file_chooser_dialog_new ("Open File",
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
//XXX check access? Dialog seems to default to "Recently used" etc.
|
||||
//Or set to empty string anyway? Then it seems to default to some sort of "working dir"
|
||||
if (access (gtk_entry_get_text (GTK_ENTRY (entry)), F_OK) == 0)
|
||||
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
|
||||
if (entry && gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
static void entryChanged(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
fprintf (stderr, "%s\n", filename);
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), filename);
|
||||
g_free (filename);
|
||||
const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
|
||||
//fprintf(stderr, "Entry text:%s\n", text);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
int MsdDevice::Configure(int port, const std::string& api, void *data)
|
||||
{
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label, *rs_cb, *vbox;
|
||||
|
||||
GtkWidget *dlg = gtk_dialog_new_with_buttons (
|
||||
"Mass Storage Settings", GTK_WINDOW (data), GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
|
||||
GtkWidget *dlg_area_box = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
|
||||
|
||||
ro_frame = gtk_frame_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX (dlg_area_box), ro_frame, TRUE, FALSE, 5);
|
||||
|
||||
ro_label = gtk_label_new ("Select USB image:");
|
||||
gtk_frame_set_label_widget (GTK_FRAME (ro_frame), ro_label);
|
||||
gtk_label_set_use_markup (GTK_LABEL (ro_label), TRUE);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER (ro_frame), vbox);
|
||||
|
||||
rs_hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), rs_hbox, FALSE, TRUE, 0);
|
||||
|
||||
GtkWidget *entry = gtk_entry_new ();
|
||||
gtk_entry_set_max_length (GTK_ENTRY (entry), MAX_PATH); //TODO max length
|
||||
|
||||
std::string var;
|
||||
if (LoadSetting(TypeName(), port, APINAME, N_CONFIG_PATH, var))
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), var.c_str());
|
||||
|
||||
g_signal_connect (entry, "changed", G_CALLBACK (entryChanged), NULL);
|
||||
|
||||
GtkWidget *button = gtk_button_new_with_label ("Browse");
|
||||
gtk_button_set_image(GTK_BUTTON (button), gtk_image_new_from_icon_name ("gtk-open", GTK_ICON_SIZE_BUTTON));
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (fileChooser), entry);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (rs_hbox), entry, TRUE, TRUE, 5);
|
||||
gtk_box_pack_start (GTK_BOX (rs_hbox), button, FALSE, FALSE, 5);
|
||||
|
||||
gtk_widget_show_all (dlg);
|
||||
gint result = gtk_dialog_run (GTK_DIALOG (dlg));
|
||||
std::string path = gtk_entry_get_text(GTK_ENTRY(entry));
|
||||
gtk_widget_destroy (dlg);
|
||||
|
||||
// Wait for all gtk events to be consumed ...
|
||||
while (gtk_events_pending ())
|
||||
gtk_main_iteration_do (FALSE);
|
||||
|
||||
if (result == GTK_RESPONSE_OK)
|
||||
static void fileChooser(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
if(SaveSetting(TypeName(), port, APINAME, N_CONFIG_PATH, path))
|
||||
return RESULT_OK;
|
||||
else
|
||||
return RESULT_FAILED;
|
||||
GtkWidget *dialog, *entry = NULL;
|
||||
|
||||
entry = (GtkWidget*)data;
|
||||
dialog = gtk_file_chooser_dialog_new("Open File",
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
//XXX check access? Dialog seems to default to "Recently used" etc.
|
||||
//Or set to empty string anyway? Then it seems to default to some sort of "working dir"
|
||||
if (access(gtk_entry_get_text(GTK_ENTRY(entry)), F_OK) == 0)
|
||||
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(GTK_ENTRY(entry)));
|
||||
|
||||
if (entry && gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
char* filename;
|
||||
|
||||
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
fprintf(stderr, "%s\n", filename);
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), filename);
|
||||
g_free(filename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
int MsdDevice::Configure(int port, const std::string& api, void* data)
|
||||
{
|
||||
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label, *rs_cb, *vbox;
|
||||
|
||||
} //namespace
|
||||
GtkWidget* dlg = gtk_dialog_new_with_buttons(
|
||||
"Mass Storage Settings", GTK_WINDOW(data), GTK_DIALOG_MODAL,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
|
||||
GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
|
||||
|
||||
ro_frame = gtk_frame_new(NULL);
|
||||
gtk_box_pack_start(GTK_BOX(dlg_area_box), ro_frame, TRUE, FALSE, 5);
|
||||
|
||||
ro_label = gtk_label_new("Select USB image:");
|
||||
gtk_frame_set_label_widget(GTK_FRAME(ro_frame), ro_label);
|
||||
gtk_label_set_use_markup(GTK_LABEL(ro_label), TRUE);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(ro_frame), vbox);
|
||||
|
||||
rs_hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), rs_hbox, FALSE, TRUE, 0);
|
||||
|
||||
GtkWidget* entry = gtk_entry_new();
|
||||
gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_PATH); //TODO max length
|
||||
|
||||
std::string var;
|
||||
if (LoadSetting(TypeName(), port, APINAME, N_CONFIG_PATH, var))
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), var.c_str());
|
||||
|
||||
g_signal_connect(entry, "changed", G_CALLBACK(entryChanged), NULL);
|
||||
|
||||
GtkWidget* button = gtk_button_new_with_label("Browse");
|
||||
gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_icon_name("gtk-open", GTK_ICON_SIZE_BUTTON));
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(fileChooser), entry);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), entry, TRUE, TRUE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), button, FALSE, FALSE, 5);
|
||||
|
||||
gtk_widget_show_all(dlg);
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
std::string path = gtk_entry_get_text(GTK_ENTRY(entry));
|
||||
gtk_widget_destroy(dlg);
|
||||
|
||||
// Wait for all gtk events to be consumed ...
|
||||
while (gtk_events_pending())
|
||||
gtk_main_iteration_do(FALSE);
|
||||
|
||||
if (result == GTK_RESPONSE_OK)
|
||||
{
|
||||
if (SaveSetting(TypeName(), port, APINAME, N_CONFIG_PATH, path))
|
||||
return RESULT_OK;
|
||||
else
|
||||
return RESULT_FAILED;
|
||||
}
|
||||
|
||||
return RESULT_CANCELED;
|
||||
}
|
||||
|
||||
} // namespace usb_msd
|
||||
|
|
|
@ -17,78 +17,84 @@
|
|||
#include "../Win32/Config.h"
|
||||
#include "../Win32/resource.h"
|
||||
|
||||
namespace usb_msd {
|
||||
|
||||
static OPENFILENAMEW ofn;
|
||||
BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
int port;
|
||||
static wchar_t buff[4096] = { 0 };
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
memset(buff, 0, sizeof(buff));
|
||||
port = (int)lParam;
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
|
||||
std::wstring var;
|
||||
if (LoadSetting(MsdDevice::TypeName(), port, APINAME, N_CONFIG_PATH, var))
|
||||
wcsncpy_s(buff, sizeof(buff), var.c_str(), countof(buff));
|
||||
SetWindowTextW(GetDlgItem(hW, IDC_EDIT1), buff);
|
||||
return TRUE;
|
||||
}
|
||||
case WM_CREATE:
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_BUTTON1:
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hW;
|
||||
ofn.lpstrTitle = L"USB image file";
|
||||
ofn.lpstrFile = buff;
|
||||
ofn.nMaxFile = countof(buff);
|
||||
ofn.lpstrFilter = L"All\0*.*\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
|
||||
if (GetOpenFileName(&ofn)) {
|
||||
SetWindowText(GetDlgItem(hW, IDC_EDIT1), ofn.lpstrFile);
|
||||
}
|
||||
break;
|
||||
case IDOK:
|
||||
{
|
||||
INT_PTR res = RESULT_OK;
|
||||
GetWindowTextW(GetDlgItem(hW, IDC_EDIT1), buff, countof(buff));
|
||||
port = (int)GetWindowLongPtr(hW, GWLP_USERDATA);
|
||||
if (!SaveSetting<std::wstring>(MsdDevice::TypeName(), port, APINAME, N_CONFIG_PATH, buff))
|
||||
res = RESULT_FAILED;
|
||||
//strcpy_s(conf.usb_img, ofn.lpstrFile);
|
||||
EndDialog(hW, res);
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int MsdDevice::Configure(int port, const std::string& api, void *data)
|
||||
namespace usb_msd
|
||||
{
|
||||
Win32Handles handles = *(Win32Handles*)data;
|
||||
return DialogBoxParam(handles.hInst,
|
||||
MAKEINTRESOURCE(IDD_DLGMSD),
|
||||
handles.hWnd,
|
||||
(DLGPROC)MsdDlgProc, port);
|
||||
}
|
||||
|
||||
}
|
||||
static OPENFILENAMEW ofn;
|
||||
BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int port;
|
||||
static wchar_t buff[4096] = {0};
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
memset(buff, 0, sizeof(buff));
|
||||
port = (int)lParam;
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
|
||||
std::wstring var;
|
||||
if (LoadSetting(MsdDevice::TypeName(), port, APINAME, N_CONFIG_PATH, var))
|
||||
wcsncpy_s(buff, sizeof(buff), var.c_str(), countof(buff));
|
||||
SetWindowTextW(GetDlgItem(hW, IDC_EDIT1), buff);
|
||||
return TRUE;
|
||||
}
|
||||
case WM_CREATE:
|
||||
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_BUTTON1:
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hW;
|
||||
ofn.lpstrTitle = L"USB image file";
|
||||
ofn.lpstrFile = buff;
|
||||
ofn.nMaxFile = countof(buff);
|
||||
ofn.lpstrFilter = L"All\0*.*\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
|
||||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
SetWindowText(GetDlgItem(hW, IDC_EDIT1), ofn.lpstrFile);
|
||||
}
|
||||
break;
|
||||
case IDOK:
|
||||
{
|
||||
INT_PTR res = RESULT_OK;
|
||||
GetWindowTextW(GetDlgItem(hW, IDC_EDIT1), buff, countof(buff));
|
||||
port = (int)GetWindowLongPtr(hW, GWLP_USERDATA);
|
||||
if (!SaveSetting<std::wstring>(MsdDevice::TypeName(), port, APINAME, N_CONFIG_PATH, buff))
|
||||
res = RESULT_FAILED;
|
||||
//strcpy_s(conf.usb_img, ofn.lpstrFile);
|
||||
EndDialog(hW, res);
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hW, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int MsdDevice::Configure(int port, const std::string& api, void* data)
|
||||
{
|
||||
Win32Handles handles = *(Win32Handles*)data;
|
||||
return DialogBoxParam(handles.hInst,
|
||||
MAKEINTRESOURCE(IDD_DLGMSD),
|
||||
handles.hWnd,
|
||||
(DLGPROC)MsdDlgProc, port);
|
||||
}
|
||||
|
||||
} // namespace usb_msd
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,31 +17,32 @@
|
|||
#define USBMSD_H
|
||||
#include "../deviceproxy.h"
|
||||
|
||||
namespace usb_msd {
|
||||
|
||||
static const char *APINAME = "cstdio";
|
||||
|
||||
class MsdDevice
|
||||
namespace usb_msd
|
||||
{
|
||||
public:
|
||||
virtual ~MsdDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const char* TypeName();
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Mass storage device");
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return std::list<std::string> { APINAME };
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
return TEXT("cstdio");
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void *data);
|
||||
static int Freeze(int mode, USBDevice *dev, void *data);
|
||||
};
|
||||
|
||||
}
|
||||
static const char* APINAME = "cstdio";
|
||||
|
||||
class MsdDevice
|
||||
{
|
||||
public:
|
||||
virtual ~MsdDevice() {}
|
||||
static USBDevice* CreateDevice(int port);
|
||||
static const char* TypeName();
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("Mass storage device");
|
||||
}
|
||||
static std::list<std::string> ListAPIs()
|
||||
{
|
||||
return std::list<std::string>{APINAME};
|
||||
}
|
||||
static const TCHAR* LongAPIName(const std::string& name)
|
||||
{
|
||||
return TEXT("cstdio");
|
||||
}
|
||||
static int Configure(int port, const std::string& api, void* data);
|
||||
static int Freeze(int mode, USBDevice* dev, void* data);
|
||||
};
|
||||
|
||||
} // namespace usb_msd
|
||||
#endif
|
||||
|
|
|
@ -23,115 +23,130 @@
|
|||
// http://stackoverflow.com/questions/3534535/whats-a-time-efficient-algorithm-to-copy-unaligned-bit-arrays
|
||||
//
|
||||
|
||||
#define PREPARE_FIRST_COPY() \
|
||||
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];\
|
||||
c &= reverse_mask[dst_offset_modulo + src_len ];\
|
||||
src_len = 0; \
|
||||
} } while (0)
|
||||
#define PREPARE_FIRST_COPY() \
|
||||
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]; \
|
||||
c &= reverse_mask[dst_offset_modulo + src_len]; \
|
||||
src_len = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
//But copies bits in reverse?
|
||||
void
|
||||
bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
|
||||
uint8_t*dst_org, int dst_offset)
|
||||
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[] =
|
||||
{ 0x55, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
|
||||
static const unsigned char reverse_mask[] =
|
||||
{ 0x55, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
|
||||
static const unsigned char reverse_mask_xor[] =
|
||||
{ 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };
|
||||
static const unsigned char mask[] =
|
||||
{0x55, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
|
||||
static const unsigned char reverse_mask[] =
|
||||
{0x55, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
|
||||
static const unsigned char reverse_mask_xor[] =
|
||||
{0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00};
|
||||
|
||||
if (src_len) {
|
||||
const unsigned char *src;
|
||||
unsigned char *dst;
|
||||
int src_offset_modulo,
|
||||
dst_offset_modulo;
|
||||
if (src_len)
|
||||
{
|
||||
const unsigned char* src;
|
||||
unsigned char* dst;
|
||||
int src_offset_modulo,
|
||||
dst_offset_modulo;
|
||||
|
||||
src = src_org + (src_offset / CHAR_BIT);
|
||||
dst = dst_org + (dst_offset / CHAR_BIT);
|
||||
src = src_org + (src_offset / CHAR_BIT);
|
||||
dst = dst_org + (dst_offset / CHAR_BIT);
|
||||
|
||||
src_offset_modulo = src_offset % CHAR_BIT;
|
||||
dst_offset_modulo = dst_offset % CHAR_BIT;
|
||||
src_offset_modulo = src_offset % CHAR_BIT;
|
||||
dst_offset_modulo = dst_offset % CHAR_BIT;
|
||||
|
||||
if (src_offset_modulo == dst_offset_modulo) {
|
||||
int byte_len;
|
||||
int src_len_modulo;
|
||||
if (src_offset_modulo) {
|
||||
unsigned char c;
|
||||
if (src_offset_modulo == dst_offset_modulo)
|
||||
{
|
||||
int byte_len;
|
||||
int src_len_modulo;
|
||||
if (src_offset_modulo)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
c = reverse_mask_xor[dst_offset_modulo] & *src++;
|
||||
c = reverse_mask_xor[dst_offset_modulo] & *src++;
|
||||
|
||||
PREPARE_FIRST_COPY();
|
||||
*dst++ |= c;
|
||||
}
|
||||
PREPARE_FIRST_COPY();
|
||||
*dst++ |= c;
|
||||
}
|
||||
|
||||
byte_len = src_len / CHAR_BIT;
|
||||
src_len_modulo = src_len % CHAR_BIT;
|
||||
byte_len = src_len / CHAR_BIT;
|
||||
src_len_modulo = src_len % CHAR_BIT;
|
||||
|
||||
if (byte_len) {
|
||||
memcpy(dst, src, byte_len);
|
||||
src += byte_len;
|
||||
dst += byte_len;
|
||||
}
|
||||
if (src_len_modulo) {
|
||||
*dst &= reverse_mask_xor[src_len_modulo];
|
||||
*dst |= reverse_mask[src_len_modulo] & *src;
|
||||
}
|
||||
} else {
|
||||
int bit_diff_ls,
|
||||
bit_diff_rs;
|
||||
int byte_len;
|
||||
int src_len_modulo;
|
||||
unsigned char c;
|
||||
/*
|
||||
if (byte_len)
|
||||
{
|
||||
memcpy(dst, src, byte_len);
|
||||
src += byte_len;
|
||||
dst += byte_len;
|
||||
}
|
||||
if (src_len_modulo)
|
||||
{
|
||||
*dst &= reverse_mask_xor[src_len_modulo];
|
||||
*dst |= reverse_mask[src_len_modulo] & *src;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int bit_diff_ls,
|
||||
bit_diff_rs;
|
||||
int byte_len;
|
||||
int src_len_modulo;
|
||||
unsigned char c;
|
||||
/*
|
||||
* Begin: Line things up on destination.
|
||||
*/
|
||||
if (src_offset_modulo > dst_offset_modulo) {
|
||||
bit_diff_ls = src_offset_modulo - dst_offset_modulo;
|
||||
bit_diff_rs = CHAR_BIT - bit_diff_ls;
|
||||
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 {
|
||||
bit_diff_rs = dst_offset_modulo - src_offset_modulo;
|
||||
bit_diff_ls = CHAR_BIT - bit_diff_rs;
|
||||
c = *src++ << bit_diff_ls;
|
||||
c |= *src >> bit_diff_rs;
|
||||
c &= reverse_mask_xor[dst_offset_modulo];
|
||||
}
|
||||
else
|
||||
{
|
||||
bit_diff_rs = dst_offset_modulo - src_offset_modulo;
|
||||
bit_diff_ls = CHAR_BIT - bit_diff_rs;
|
||||
|
||||
c = *src >> bit_diff_rs &
|
||||
reverse_mask_xor[dst_offset_modulo];
|
||||
}
|
||||
PREPARE_FIRST_COPY();
|
||||
*dst++ |= c;
|
||||
c = *src >> bit_diff_rs &
|
||||
reverse_mask_xor[dst_offset_modulo];
|
||||
}
|
||||
PREPARE_FIRST_COPY();
|
||||
*dst++ |= c;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Middle: copy with only shifting the source.
|
||||
*/
|
||||
byte_len = src_len / CHAR_BIT;
|
||||
byte_len = src_len / CHAR_BIT;
|
||||
|
||||
while (--byte_len >= 0) {
|
||||
c = *src++ << bit_diff_ls;
|
||||
c |= *src >> bit_diff_rs;
|
||||
*dst++ = c;
|
||||
}
|
||||
while (--byte_len >= 0)
|
||||
{
|
||||
c = *src++ << bit_diff_ls;
|
||||
c |= *src >> bit_diff_rs;
|
||||
*dst++ = c;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* End: copy the remaing bits;
|
||||
*/
|
||||
src_len_modulo = src_len % CHAR_BIT;
|
||||
if (src_len_modulo) {
|
||||
c = *src++ << bit_diff_ls;
|
||||
c |= *src >> bit_diff_rs;
|
||||
c &= reverse_mask[src_len_modulo];
|
||||
src_len_modulo = src_len % CHAR_BIT;
|
||||
if (src_len_modulo)
|
||||
{
|
||||
c = *src++ << bit_diff_ls;
|
||||
c |= *src >> bit_diff_rs;
|
||||
c &= reverse_mask[src_len_modulo];
|
||||
|
||||
*dst &= reverse_mask_xor[src_len_modulo];
|
||||
*dst |= c;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst &= reverse_mask_xor[src_len_modulo];
|
||||
*dst |= c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -33,178 +33,187 @@
|
|||
|
||||
#define DINPUT_AXES_COUNT 32
|
||||
|
||||
namespace usb_pad { namespace dx {
|
||||
|
||||
extern int32_t BYPASSCAL;
|
||||
|
||||
//dinput control mappings
|
||||
|
||||
static const DWORD PRECMULTI = 100; //floating point precision multiplier, 100 - two digit precision after comma
|
||||
|
||||
extern int32_t GAINZ[2][1];
|
||||
extern int32_t FFMULTI[2][1];
|
||||
extern int32_t INVERTFORCES[2];
|
||||
|
||||
static bool didDIinit = false; //we have a handle
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, REFGUID guid);
|
||||
|
||||
enum ControlID
|
||||
namespace usb_pad
|
||||
{
|
||||
CID_STEERING,
|
||||
CID_STEERING_R,
|
||||
CID_THROTTLE,
|
||||
CID_BRAKE,
|
||||
CID_HATUP,
|
||||
CID_HATDOWN,
|
||||
CID_HATLEFT,
|
||||
CID_HATRIGHT,
|
||||
CID_SQUARE,
|
||||
CID_TRIANGLE,
|
||||
CID_CROSS,
|
||||
CID_CIRCLE,
|
||||
CID_L1,
|
||||
CID_R1,
|
||||
CID_L2,
|
||||
CID_R2,
|
||||
CID_L3,
|
||||
CID_R3,
|
||||
CID_SELECT,
|
||||
CID_START,
|
||||
CID_COUNT,
|
||||
};
|
||||
|
||||
// Maybe merge with JoystickDevice
|
||||
class JoystickDeviceFF : public FFDevice
|
||||
{
|
||||
public:
|
||||
JoystickDeviceFF(int port): m_port(port) {}
|
||||
~JoystickDeviceFF() {}
|
||||
|
||||
void SetConstantForce(int level);
|
||||
void SetSpringForce(const parsed_ff_data& ff);
|
||||
void SetDamperForce(const parsed_ff_data& ff);
|
||||
void SetFrictionForce(const parsed_ff_data& ff);
|
||||
void SetAutoCenter(int value);
|
||||
void DisableForce(EffectID force);
|
||||
|
||||
private:
|
||||
int m_port;
|
||||
};
|
||||
|
||||
enum ControlType
|
||||
{
|
||||
CT_NONE,
|
||||
CT_KEYBOARD,
|
||||
CT_MOUSE,
|
||||
CT_JOYSTICK,
|
||||
};
|
||||
|
||||
enum MappingType
|
||||
{
|
||||
MT_NONE = 0, //TODO leave for sanity checking?
|
||||
MT_AXIS,
|
||||
MT_BUTTON,
|
||||
};
|
||||
|
||||
struct InputMapped
|
||||
{
|
||||
size_t index; //index into g_pJoysticks
|
||||
MappingType type = MT_NONE;
|
||||
int32_t mapped; //device axis/button
|
||||
bool INVERTED;
|
||||
int32_t HALF;
|
||||
int32_t LINEAR;
|
||||
int32_t OFFSET;
|
||||
int32_t DEADZONE;
|
||||
};
|
||||
|
||||
class JoystickDevice
|
||||
{
|
||||
public:
|
||||
JoystickDevice(ControlType type, LPDIRECTINPUTDEVICE8 device, GUID guid, TSTDSTRING name)
|
||||
: m_type(type)
|
||||
, m_guid(guid)
|
||||
, m_device(device)
|
||||
, m_product(name)
|
||||
namespace dx
|
||||
{
|
||||
}
|
||||
|
||||
bool Poll();
|
||||
extern int32_t BYPASSCAL;
|
||||
|
||||
/*void GetDeviceState(size_t sz, void *ptr)
|
||||
//dinput control mappings
|
||||
|
||||
static const DWORD PRECMULTI = 100; //floating point precision multiplier, 100 - two digit precision after comma
|
||||
|
||||
extern int32_t GAINZ[2][1];
|
||||
extern int32_t FFMULTI[2][1];
|
||||
extern int32_t INVERTFORCES[2];
|
||||
|
||||
static bool didDIinit = false; //we have a handle
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, REFGUID guid);
|
||||
|
||||
enum ControlID
|
||||
{
|
||||
CID_STEERING,
|
||||
CID_STEERING_R,
|
||||
CID_THROTTLE,
|
||||
CID_BRAKE,
|
||||
CID_HATUP,
|
||||
CID_HATDOWN,
|
||||
CID_HATLEFT,
|
||||
CID_HATRIGHT,
|
||||
CID_SQUARE,
|
||||
CID_TRIANGLE,
|
||||
CID_CROSS,
|
||||
CID_CIRCLE,
|
||||
CID_L1,
|
||||
CID_R1,
|
||||
CID_L2,
|
||||
CID_R2,
|
||||
CID_L3,
|
||||
CID_R3,
|
||||
CID_SELECT,
|
||||
CID_START,
|
||||
CID_COUNT,
|
||||
};
|
||||
|
||||
// Maybe merge with JoystickDevice
|
||||
class JoystickDeviceFF : public FFDevice
|
||||
{
|
||||
public:
|
||||
JoystickDeviceFF(int port)
|
||||
: m_port(port)
|
||||
{
|
||||
}
|
||||
~JoystickDeviceFF() {}
|
||||
|
||||
void SetConstantForce(int level);
|
||||
void SetSpringForce(const parsed_ff_data& ff);
|
||||
void SetDamperForce(const parsed_ff_data& ff);
|
||||
void SetFrictionForce(const parsed_ff_data& ff);
|
||||
void SetAutoCenter(int value);
|
||||
void DisableForce(EffectID force);
|
||||
|
||||
private:
|
||||
int m_port;
|
||||
};
|
||||
|
||||
enum ControlType
|
||||
{
|
||||
CT_NONE,
|
||||
CT_KEYBOARD,
|
||||
CT_MOUSE,
|
||||
CT_JOYSTICK,
|
||||
};
|
||||
|
||||
enum MappingType
|
||||
{
|
||||
MT_NONE = 0, //TODO leave for sanity checking?
|
||||
MT_AXIS,
|
||||
MT_BUTTON,
|
||||
};
|
||||
|
||||
struct InputMapped
|
||||
{
|
||||
size_t index; //index into g_pJoysticks
|
||||
MappingType type = MT_NONE;
|
||||
int32_t mapped; //device axis/button
|
||||
bool INVERTED;
|
||||
int32_t HALF;
|
||||
int32_t LINEAR;
|
||||
int32_t OFFSET;
|
||||
int32_t DEADZONE;
|
||||
};
|
||||
|
||||
class JoystickDevice
|
||||
{
|
||||
public:
|
||||
JoystickDevice(ControlType type, LPDIRECTINPUTDEVICE8 device, GUID guid, TSTDSTRING name)
|
||||
: m_type(type)
|
||||
, m_guid(guid)
|
||||
, m_device(device)
|
||||
, m_product(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool Poll();
|
||||
|
||||
/*void GetDeviceState(size_t sz, void *ptr)
|
||||
{
|
||||
if (sz == sizeof(DIJOYSTATE2) && ptr)
|
||||
*ptr = m_jstate;
|
||||
}*/
|
||||
|
||||
DIJOYSTATE2 GetDeviceState()
|
||||
{
|
||||
//assert(m_type == CT_JOYSTICK);
|
||||
return m_controls.js2;
|
||||
}
|
||||
DIJOYSTATE2 GetDeviceState()
|
||||
{
|
||||
//assert(m_type == CT_JOYSTICK);
|
||||
return m_controls.js2;
|
||||
}
|
||||
|
||||
HRESULT GetDeviceState(DWORD sz, LPVOID ptr)
|
||||
{
|
||||
return m_device->GetDeviceState(sz, ptr);
|
||||
}
|
||||
HRESULT GetDeviceState(DWORD sz, LPVOID ptr)
|
||||
{
|
||||
return m_device->GetDeviceState(sz, ptr);
|
||||
}
|
||||
|
||||
bool GetButton(int b);
|
||||
LONG GetAxis(int a);
|
||||
bool GetButton(int b);
|
||||
LONG GetAxis(int a);
|
||||
|
||||
LPDIRECTINPUTDEVICE8 GetDevice()
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
LPDIRECTINPUTDEVICE8 GetDevice()
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
|
||||
GUID GetGUID()
|
||||
{
|
||||
return m_guid;
|
||||
}
|
||||
GUID GetGUID()
|
||||
{
|
||||
return m_guid;
|
||||
}
|
||||
|
||||
const TSTDSTRING& Product() const
|
||||
{
|
||||
return m_product;
|
||||
}
|
||||
const TSTDSTRING& Product() const
|
||||
{
|
||||
return m_product;
|
||||
}
|
||||
|
||||
ControlType GetControlType() { return m_type; }
|
||||
ControlType GetControlType() { return m_type; }
|
||||
|
||||
~JoystickDevice();
|
||||
private:
|
||||
GUID m_guid;
|
||||
TSTDSTRING m_product;
|
||||
LPDIRECTINPUTDEVICE8 m_device;
|
||||
ControlType m_type = CT_NONE;
|
||||
union {
|
||||
DIJOYSTATE2 js2;
|
||||
DIMOUSESTATE2 ms2;
|
||||
BYTE kbd[256];
|
||||
} m_controls = {};
|
||||
};
|
||||
~JoystickDevice();
|
||||
|
||||
extern std::vector<JoystickDevice *> g_pJoysticks;
|
||||
extern std::map<int, InputMapped> g_Controls[2];
|
||||
private:
|
||||
GUID m_guid;
|
||||
TSTDSTRING m_product;
|
||||
LPDIRECTINPUTDEVICE8 m_device;
|
||||
ControlType m_type = CT_NONE;
|
||||
union
|
||||
{
|
||||
DIJOYSTATE2 js2;
|
||||
DIMOUSESTATE2 ms2;
|
||||
BYTE kbd[256];
|
||||
} m_controls = {};
|
||||
};
|
||||
|
||||
void LoadDInputConfig(int port, const char *dev_type);
|
||||
void SaveDInputConfig(int port, const char *dev_type);
|
||||
extern std::vector<JoystickDevice*> g_pJoysticks;
|
||||
extern std::map<int, InputMapped> g_Controls[2];
|
||||
|
||||
void InitDI(int port, const char *dev_type);
|
||||
HRESULT InitDirectInput( HWND hWindow, int port );
|
||||
void FreeDirectInput();
|
||||
void PollDevices();
|
||||
float ReadAxis(const InputMapped& im);
|
||||
float ReadAxis(int port, ControlID axisid);
|
||||
float FilterControl(float input, LONG linear, LONG offset, LONG dead);
|
||||
bool KeyDown(DWORD KeyID);
|
||||
void TestForce(int port);
|
||||
LONG GetAxisValueFromOffset(int axis, const DIJOYSTATE2& j);
|
||||
bool GetControl(int port, int id);
|
||||
float GetAxisControl(int port, ControlID id);
|
||||
void CreateFFB(int port, LPDIRECTINPUTDEVICE8 device, DWORD axis);
|
||||
bool FindFFDevice(int port);
|
||||
void LoadDInputConfig(int port, const char* dev_type);
|
||||
void SaveDInputConfig(int port, const char* dev_type);
|
||||
|
||||
void AddInputMap(int port, int cid, const InputMapped& im);
|
||||
void RemoveInputMap(int port, int cid);
|
||||
bool GetInputMap(int port, int cid, InputMapped& im);
|
||||
void InitDI(int port, const char* dev_type);
|
||||
HRESULT InitDirectInput(HWND hWindow, int port);
|
||||
void FreeDirectInput();
|
||||
void PollDevices();
|
||||
float ReadAxis(const InputMapped& im);
|
||||
float ReadAxis(int port, ControlID axisid);
|
||||
float FilterControl(float input, LONG linear, LONG offset, LONG dead);
|
||||
bool KeyDown(DWORD KeyID);
|
||||
void TestForce(int port);
|
||||
LONG GetAxisValueFromOffset(int axis, const DIJOYSTATE2& j);
|
||||
bool GetControl(int port, int id);
|
||||
float GetAxisControl(int port, ControlID id);
|
||||
void CreateFFB(int port, LPDIRECTINPUTDEVICE8 device, DWORD axis);
|
||||
bool FindFFDevice(int port);
|
||||
|
||||
}} //namespace
|
||||
void AddInputMap(int port, int cid, const InputMapped& im);
|
||||
void RemoveInputMap(int port, int cid);
|
||||
bool GetInputMap(int port, int cid, InputMapped& im);
|
||||
|
||||
} // namespace dx
|
||||
} // namespace usb_pad
|
||||
|
|
|
@ -17,128 +17,155 @@
|
|||
#include "dx.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace usb_pad { namespace dx {
|
||||
|
||||
static bool bdown=false;
|
||||
static DWORD calibrationtime = 0;
|
||||
static int calidata = 0;
|
||||
static bool alternate = false;
|
||||
static bool calibrating = false;
|
||||
|
||||
DInputPad::~DInputPad() { FreeDirectInput(); }
|
||||
|
||||
int DInputPad::TokenIn(uint8_t *buf, int len)
|
||||
namespace usb_pad
|
||||
{
|
||||
int range = range_max(mType);
|
||||
namespace dx
|
||||
{
|
||||
|
||||
// Setting to unpressed
|
||||
ZeroMemory(&mWheelData, sizeof(wheel_data_t));
|
||||
mWheelData.steering = range >> 1;
|
||||
mWheelData.clutch = 0xFF;
|
||||
mWheelData.throttle = 0xFF;
|
||||
mWheelData.brake = 0xFF;
|
||||
mWheelData.hatswitch = 0x8;
|
||||
static bool bdown = false;
|
||||
static DWORD calibrationtime = 0;
|
||||
static int calidata = 0;
|
||||
static bool alternate = false;
|
||||
static bool calibrating = false;
|
||||
|
||||
PollDevices();
|
||||
DInputPad::~DInputPad() { FreeDirectInput(); }
|
||||
|
||||
if (mType == WT_BUZZ_CONTROLLER) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (GetControl(mPort, i)) {
|
||||
mWheelData.buttons |= 1 << i;
|
||||
int DInputPad::TokenIn(uint8_t* buf, int len)
|
||||
{
|
||||
int range = range_max(mType);
|
||||
|
||||
// Setting to unpressed
|
||||
ZeroMemory(&mWheelData, sizeof(wheel_data_t));
|
||||
mWheelData.steering = range >> 1;
|
||||
mWheelData.clutch = 0xFF;
|
||||
mWheelData.throttle = 0xFF;
|
||||
mWheelData.brake = 0xFF;
|
||||
mWheelData.hatswitch = 0x8;
|
||||
|
||||
PollDevices();
|
||||
|
||||
if (mType == WT_BUZZ_CONTROLLER)
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
if (GetControl(mPort, i))
|
||||
{
|
||||
mWheelData.buttons |= 1 << i;
|
||||
}
|
||||
}
|
||||
pad_copy_data(mType, buf, mWheelData);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
pad_copy_data(mType, buf, mWheelData);
|
||||
return 5;
|
||||
}
|
||||
|
||||
//Allow in both ports but warn in configure dialog that only one DX wheel is supported for now
|
||||
//if(idx == 0){
|
||||
//mWheelData.steering = 8191 + (int)(GetControl(STEERING, false)* 8191.0f) ;
|
||||
|
||||
if(calibrating){
|
||||
//Alternate full extents
|
||||
if (alternate)calidata--;
|
||||
else calidata++;
|
||||
//Allow in both ports but warn in configure dialog that only one DX wheel is supported for now
|
||||
//if(idx == 0){
|
||||
//mWheelData.steering = 8191 + (int)(GetControl(STEERING, false)* 8191.0f) ;
|
||||
|
||||
if(calidata>range-1 || calidata < 1) alternate = !alternate; //invert
|
||||
if (calibrating)
|
||||
{
|
||||
//Alternate full extents
|
||||
if (alternate)
|
||||
calidata--;
|
||||
else
|
||||
calidata++;
|
||||
|
||||
mWheelData.steering = calidata; //pass fake
|
||||
if (calidata > range - 1 || calidata < 1)
|
||||
alternate = !alternate; //invert
|
||||
|
||||
//breakout after 11 seconds
|
||||
if(GetTickCount()-calibrationtime > 11000){
|
||||
calibrating = false;
|
||||
mWheelData.steering = range >> 1;
|
||||
mWheelData.steering = calidata; //pass fake
|
||||
|
||||
//breakout after 11 seconds
|
||||
if (GetTickCount() - calibrationtime > 11000)
|
||||
{
|
||||
calibrating = false;
|
||||
mWheelData.steering = range >> 1;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
mWheelData.steering = (range>>1) + std::lround(GetAxisControl(mPort, CID_STEERING) * (float)(range>>1));
|
||||
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_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))
|
||||
mWheelData.hatswitch = 1;
|
||||
if (GetControl(mPort, CID_HATRIGHT) && GetControl(mPort, CID_HATDOWN))
|
||||
mWheelData.hatswitch = 3;
|
||||
if (GetControl(mPort, CID_HATDOWN) && GetControl(mPort, CID_HATLEFT))
|
||||
mWheelData.hatswitch = 5;
|
||||
if (GetControl(mPort, CID_HATLEFT) && GetControl(mPort, CID_HATUP))
|
||||
mWheelData.hatswitch = 7;
|
||||
|
||||
//regular
|
||||
if (mWheelData.hatswitch == 0x8)
|
||||
{
|
||||
if (GetControl(mPort, CID_HATUP))
|
||||
mWheelData.hatswitch = 0;
|
||||
if (GetControl(mPort, CID_HATRIGHT))
|
||||
mWheelData.hatswitch = 2;
|
||||
if (GetControl(mPort, CID_HATDOWN))
|
||||
mWheelData.hatswitch = 4;
|
||||
if (GetControl(mPort, CID_HATLEFT))
|
||||
mWheelData.hatswitch = 6;
|
||||
}
|
||||
|
||||
pad_copy_data(mType, buf, mWheelData);
|
||||
//} //if(idx ...
|
||||
return len;
|
||||
}
|
||||
|
||||
mWheelData.throttle = std::lround(255.f - (GetAxisControl(mPort, CID_THROTTLE) * 255.0f));
|
||||
mWheelData.brake = std::lround(255.f - (GetAxisControl(mPort, CID_BRAKE) * 255.0f));
|
||||
int DInputPad::TokenOut(const uint8_t* data, int len)
|
||||
{
|
||||
const ff_data* ffdata = (const ff_data*)data;
|
||||
bool hires = (mType == WT_DRIVING_FORCE_PRO || mType == WT_DRIVING_FORCE_PRO_1102);
|
||||
ParseFFData(ffdata, hires);
|
||||
|
||||
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);
|
||||
|
||||
//diagonal
|
||||
if(GetControl(mPort, CID_HATUP) && GetControl(mPort, CID_HATRIGHT))
|
||||
mWheelData.hatswitch = 1;
|
||||
if(GetControl(mPort, CID_HATRIGHT) && GetControl(mPort, CID_HATDOWN))
|
||||
mWheelData.hatswitch = 3;
|
||||
if(GetControl(mPort, CID_HATDOWN) && GetControl(mPort, CID_HATLEFT))
|
||||
mWheelData.hatswitch = 5;
|
||||
if(GetControl(mPort, CID_HATLEFT) && GetControl(mPort, CID_HATUP))
|
||||
mWheelData.hatswitch = 7;
|
||||
|
||||
//regular
|
||||
if(mWheelData.hatswitch==0x8){
|
||||
if(GetControl(mPort, CID_HATUP))
|
||||
mWheelData.hatswitch = 0;
|
||||
if(GetControl(mPort, CID_HATRIGHT))
|
||||
mWheelData.hatswitch = 2;
|
||||
if(GetControl(mPort, CID_HATDOWN))
|
||||
mWheelData.hatswitch = 4;
|
||||
if(GetControl(mPort, CID_HATLEFT))
|
||||
mWheelData.hatswitch = 6;
|
||||
return len;
|
||||
}
|
||||
|
||||
pad_copy_data(mType, buf, mWheelData);
|
||||
//} //if(idx ...
|
||||
return len;
|
||||
}
|
||||
int DInputPad::Open()
|
||||
{
|
||||
LoadSetting(mDevType, mPort, APINAME, TEXT("UseRamp"), mUseRamp);
|
||||
InitDI(mPort, mDevType);
|
||||
if (!mFFdev)
|
||||
mFFdev = new JoystickDeviceFF(mPort /*, mUseRamp*/);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DInputPad::TokenOut(const uint8_t *data, int len)
|
||||
{
|
||||
const ff_data *ffdata = (const ff_data *)data;
|
||||
bool hires = (mType == WT_DRIVING_FORCE_PRO || mType == WT_DRIVING_FORCE_PRO_1102);
|
||||
ParseFFData(ffdata, hires);
|
||||
int DInputPad::Close()
|
||||
{
|
||||
FreeDirectInput();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int DInputPad::Open()
|
||||
{
|
||||
LoadSetting(mDevType, mPort, APINAME, TEXT("UseRamp"), mUseRamp);
|
||||
InitDI(mPort, mDevType);
|
||||
if (!mFFdev)
|
||||
mFFdev = new JoystickDeviceFF(mPort /*, mUseRamp*/);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DInputPad::Close()
|
||||
{
|
||||
FreeDirectInput();
|
||||
return 0;
|
||||
}
|
||||
|
||||
}} //namespace
|
||||
} // namespace dx
|
||||
} // namespace usb_pad
|
||||
|
|
|
@ -16,29 +16,38 @@
|
|||
#include "../padproxy.h"
|
||||
#include "../../Win32/Config.h"
|
||||
|
||||
namespace usb_pad { namespace dx {
|
||||
|
||||
static const char *APINAME = "dinput";
|
||||
|
||||
class DInputPad : public Pad
|
||||
namespace usb_pad
|
||||
{
|
||||
public:
|
||||
DInputPad(int port, const char* dev_type) : Pad(port, dev_type), mUseRamp(0){}
|
||||
~DInputPad();
|
||||
int Open();
|
||||
int Close();
|
||||
int TokenIn(uint8_t *buf, int len);
|
||||
int TokenOut(const uint8_t *data, int len);
|
||||
int Reset() { return 0; }
|
||||
|
||||
static const TCHAR* Name()
|
||||
namespace dx
|
||||
{
|
||||
return TEXT("DInput");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void *data);
|
||||
private:
|
||||
int32_t mUseRamp;
|
||||
};
|
||||
static const char* APINAME = "dinput";
|
||||
|
||||
}} //namespace
|
||||
class DInputPad : public Pad
|
||||
{
|
||||
public:
|
||||
DInputPad(int port, const char* dev_type)
|
||||
: Pad(port, dev_type)
|
||||
, mUseRamp(0)
|
||||
{
|
||||
}
|
||||
~DInputPad();
|
||||
int Open();
|
||||
int Close();
|
||||
int TokenIn(uint8_t* buf, int len);
|
||||
int TokenOut(const uint8_t* data, int len);
|
||||
int Reset() { return 0; }
|
||||
|
||||
static const TCHAR* Name()
|
||||
{
|
||||
return TEXT("DInput");
|
||||
}
|
||||
|
||||
static int Configure(int port, const char* dev_type, void* data);
|
||||
|
||||
private:
|
||||
int32_t mUseRamp;
|
||||
};
|
||||
|
||||
} // namespace dx
|
||||
} // namespace usb_pad
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue