Example #1
0
DXInput::~DXInput()
{
    traceIn(DXInput::~DXInput);

    bInputExiting = 1;

    SetEvent(InputEvents[0]);
    SetEvent(InputEvents[1]);
    //WaitForSingleObject(hInputThread, 5000);
    //CloseHandle(hInputThread);
    diKeyboard->SetEventNotification(NULL);
    diMouse->SetEventNotification(NULL);
    CloseHandle(InputEvents[0]);
    CloseHandle(InputEvents[1]);

    DIDestroyKeyboardDevice();
    DIDestroyMouseDevice();
    diDevice->Release();

    bDInputActive = 0;

    Log(TEXT("DirectInput Freed"));

    traceOut;
}
Example #2
0
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT InitDirectInput( HWND hWnd )
{
    HRESULT hr;

    // Register with the DirectInput subsystem and get a pointer
    // to a IDirectInput interface we can use.
    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;
    
    // Obtain an interface to the system mouse device.
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL ) ) )
        return hr;

    // Set the data format to "mouse format" - a predefined data format 
    //
    // A data format specifies which controls on a device we
    // are interested in, and how they should be reported.
    //
    // This tells DirectInput that we will be passing a
    // DIMOUSESTATE structure to IDirectInputDevice::GetDeviceState.
    if( FAILED( hr = g_pMouse->SetDataFormat( &c_dfDIMouse ) ) )
        return hr;

    // Set the cooperativity level to let DirectInput know how
    // this device should interact with the system and with other
    // DirectInput applications.
    if( FAILED( hr = g_pMouse->SetCooperativeLevel( hWnd, 
                                         DISCL_EXCLUSIVE|DISCL_FOREGROUND ) ) )
        return hr;

    // Create a win32 event which is signaled when mouse data is availible
    g_hMouseEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    if( NULL == g_hMouseEvent )
        return E_FAIL;

    // Give the event to the mouse device
    if( FAILED( hr = g_pMouse->SetEventNotification( g_hMouseEvent ) ) )
        return hr;

    // Setup the buffer size for the mouse data
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

    if( FAILED( hr = g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
        return hr;

    // Not necessary, but nice for left handed users that have
    // their swapped mouse buttons
    g_bSwapMouseButtons = GetSystemMetrics( SM_SWAPBUTTON );

    return S_OK;
}
Example #3
0
void WINAPI DICreateKeyboardDevice(HANDLE window)
{
    traceIn(DICreateKeyboardDevice);

    if(bDInputActive)
    {
        HRESULT result;

        if(diDevice->CreateDevice(GUID_SysKeyboard, &diKeyboard, NULL) != DI_OK)
            CrashError(TEXT("DInput: Could not Create Keyboard device"));

        if(diKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
            CrashError(TEXT("DInput: Could not set keyboard data format"));

        if(diKeyboard->SetCooperativeLevel((HWND)window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
            CrashError(TEXT("DInput: Could not set keyboard cooperation level"));


        if((result = diKeyboard->SetEventNotification(InputEvents[0])) != DI_OK)
            CrashError(TEXT("DInput: couldn't set a keyboard notification.  that sucks."));

        if((result = diKeyboard->Acquire()) != DI_OK)
        {
            if(result != DIERR_OTHERAPPHASPRIO)
                CrashError(TEXT("DInput: Could not aquire keyboard device"));
        }

        if((result = diKeyboard->GetDeviceState(256, keys)) != DI_OK)
        {
            if((result != DIERR_OTHERAPPHASPRIO) && (result != DIERR_NOTACQUIRED))
                CrashError(TEXT("DInput: Could not get keyboard device state"));
        }
        /*else
        {
            keys[DIK_LSHIFT] |= keys[DIK_RSHIFT];
            keys[DIK_RSHIFT] = 0;

            keys[DIK_LCONTROL] |= keys[DIK_RCONTROL];
            keys[DIK_RCONTROL] = 0;
        }*/
    }

    traceOut;
}
Example #4
0
void WINAPI DICreateMouseDevice(HANDLE window)
{
    traceIn(DICreateMouseDevice);

    if(bDInputActive)
    {
        HRESULT result;

        if(diDevice->CreateDevice(GUID_SysMouse, &diMouse, NULL) != DI_OK)
            CrashError(TEXT("DInput: Could not Create Mouse device"));
        if(diMouse->SetDataFormat(&c_dfDIMouse) != DI_OK)
            CrashError(TEXT("DInput: Could not set mouse data format"));
        if(diMouse->SetCooperativeLevel((HWND)window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
            CrashError(TEXT("DInput: Could not set mouse cooperation level"));

        if((result = diMouse->SetEventNotification(InputEvents[1])) != DI_OK)
            CrashError(TEXT("DInput: couldn't set a mouse notification.  that sucks."));

        if((result = diMouse->Acquire()) != DI_OK)
        {
            if(result != DIERR_OTHERAPPHASPRIO)
                CrashError(TEXT("DInput: Could not aquire mouse device"));
        }

        if((result = diMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mousestate)) != DI_OK)
        {
            if((result != DIERR_OTHERAPPHASPRIO) && (result != DIERR_NOTACQUIRED))
                CrashError(TEXT("DInput: Could not get mouse state"));

            curMouseButtonStates = 0;
        }
        else
        {
            if(mousestate.rgbButtons[0])
                curMouseButtonStates |= STATE_LBUTTONDOWN;
            if(mousestate.rgbButtons[1])
                curMouseButtonStates |= STATE_MBUTTONDOWN;
            if(mousestate.rgbButtons[2])
                curMouseButtonStates |= STATE_RBUTTONDOWN;
        }
    }

    traceOut;
}
void PsychHIDOSKbQueueStart(int deviceIndex)
{
    LPDIRECTINPUTDEVICE8 kb;
    DIPROPDWORD  dipdw;
    psych_bool queueActive;
    int i;

    if (deviceIndex < 0) {
        deviceIndex = PsychHIDGetDefaultKbQueueDevice();
        // Ok, deviceIndex now contains our default keyboard to use - The first suitable keyboard.
    }

    if ((deviceIndex < 0) || (deviceIndex >= ndevices)) {
        // Out of range index:
        PsychErrorExitMsg(PsychError_user, "Invalid 'deviceIndex' specified. No such device!");
    }

    // Does Keyboard queue for this deviceIndex already exist?
    if (NULL == psychHIDKbQueueFirstPress[deviceIndex]) {
        // No. Bad bad...
        printf("PsychHID-ERROR: Tried to start processing on non-existent keyboard queue for deviceIndex %i! Call KbQueueCreate first!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Invalid keyboard 'deviceIndex' specified. No queue for that device yet!");
    }

    // Keyboard queue already stopped? Then we ain't nothing to do:
    if (psychHIDKbQueueActive[deviceIndex]) return;

    // Queue is inactive. Start it:

    // Will this be the first active queue, ie., aren't there any queues running so far?
    queueActive = FALSE;
    for (i = 0; i < PSYCH_HID_MAX_DEVICES; i++) {
        queueActive |= psychHIDKbQueueActive[i];
    }

    PsychLockMutex(&KbQueueMutex);

    // Clear out current state for this queue:
    memset(psychHIDKbQueueFirstPress[deviceIndex]   , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueFirstRelease[deviceIndex] , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastPress[deviceIndex]    , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastRelease[deviceIndex]  , 0, (256 * sizeof(double)));

    // Setup event mask, so events from our associated xinput device
    // get enqueued in our event queue:
    kb = GetXDevice(deviceIndex);

    // Device specific data format setup:
    switch (info[deviceIndex].dwDevType & 0xff) {
    case DI8DEVTYPE_KEYBOARD:
        if (DI_OK != kb->SetDataFormat(&c_dfDIKeyboard)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;

    case DI8DEVTYPE_MOUSE:
    case DI8DEVTYPE_SCREENPOINTER:
        if (DI_OK != kb->SetDataFormat(&c_dfDIMouse2)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;

    case DI8DEVTYPE_JOYSTICK:
        if (DI_OK != kb->SetDataFormat(&c_dfDIJoystick2)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;
    }

    // Set device event buffer size to 256 elements:
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = 256;

    if (DI_OK != kb->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting buffersize on device failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    // Enable state-change event notifications:
    if (DI_OK != kb->SetEventNotification(hEvent)) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting device state notifications failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    if (DI_OK != kb->Acquire()) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but acquiring device failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    // Mark this queue as logically started:
    psychHIDKbQueueActive[deviceIndex] = TRUE;

    // Queue started.
    PsychUnlockMutex(&KbQueueMutex);

    // If other queues are already active then we're done:
    if (queueActive) return;

    // No other active queues. We are the first one.

    // Start the common processing thread for all queues:
    PsychLockMutex(&KbQueueMutex);
    KbQueueThreadTerminate = FALSE;

    if (PsychCreateThread(&KbQueueThread, NULL, KbQueueWorkerThreadMain, NULL)) {
        // We are soo screwed:

        // Cleanup the mess:
        psychHIDKbQueueActive[deviceIndex] = FALSE;
        PsychUnlockMutex(&KbQueueMutex);

        // Whine a little bit:
        printf("PsychHID-ERROR: Start of keyboard queue processing failed!\n");
        PsychErrorExitMsg(PsychError_system, "Creation of keyboard queue background processing thread failed!");
    }

    // Up and running, we're done!
    PsychUnlockMutex(&KbQueueMutex);

    return;
}
void PsychHIDOSKbQueueStop(int deviceIndex)
{
    LPDIRECTINPUTDEVICE8 kb;
    psych_bool queueActive;
    int i;

    if (deviceIndex < 0) {
        deviceIndex = PsychHIDGetDefaultKbQueueDevice();
        // Ok, deviceIndex now contains our default keyboard to use - The first suitable keyboard.
    }

    if ((deviceIndex < 0) || (deviceIndex >= ndevices)) {
        // Out of range index:
        PsychErrorExitMsg(PsychError_user, "Invalid 'deviceIndex' specified. No such device!");
    }

    // Keyboard queue for this deviceIndex already exists?
    if (NULL == psychHIDKbQueueFirstPress[deviceIndex]) {
        // No. Nothing to do then.
        return;
    }

    // Keyboard queue already stopped?
    if (!psychHIDKbQueueActive[deviceIndex]) return;

    // Get device:
    kb = GetXDevice(deviceIndex);

    // Queue is active. Stop it:
    PsychLockMutex(&KbQueueMutex);

    // Release the device:
    if (DI_OK != kb->Unacquire()) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to stop processing on keyboard queue for deviceIndex %i, but releasing device failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Stopping keyboard queue failed!");
    }

    // Disable state-change event notifications:
    if (DI_OK != kb->SetEventNotification(NULL)) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to stop processing on keyboard queue for deviceIndex %i, but disabling device state notifications failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Stopping keyboard queue failed!");
    }

    // Mark queue logically stopped:
    psychHIDKbQueueActive[deviceIndex] = FALSE;

    PsychUnlockMutex(&KbQueueMutex);

    // Was this the last active queue?
    queueActive = FALSE;
    for (i = 0; i < PSYCH_HID_MAX_DEVICES; i++) {
        queueActive |= psychHIDKbQueueActive[i];
    }

    // If more queues are active then we're done:
    if (queueActive) return;

    // No more active queues. Shutdown the common processing thread:
    PsychLockMutex(&KbQueueMutex);

    KbQueueThreadTerminate = TRUE;

    // Done.
    PsychUnlockMutex(&KbQueueMutex);

    // Shutdown the thread, wait for its termination:
    PsychDeleteThread(&KbQueueThread);
    KbQueueThreadTerminate = FALSE;

    // printf("DEBUG: THREAD JOINED.\n"); fflush(NULL);

    return;
}
 HRESULT _stdcall SetEventNotification(HANDLE a) {
     return RealDevice->SetEventNotification(a);
 }
Example #8
0
int main(int argc, wchar_t* argv[])
{
	try
	{
		HWND wnd;
		if (FAILED(wnd = CreateWindow(NULL, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL)))
			throw "Can't create message window";

		LPDIRECTINPUT8 di;
		if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di, NULL)))
			throw "Can't create directinput";

		LPDIRECTINPUTDEVICE8 dev;

		if (FAILED(di->CreateDevice(GUID_SysKeyboard, &dev, NULL)))
			throw "Can't create device";

		if (FAILED(dev->SetDataFormat(&c_dfDIKeyboard)))
			throw "Can't set keyboard format";

		if (FAILED(dev->SetCooperativeLevel(wnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
			throw "Can't set cooperative level.";

		HANDLE ev = CreateEvent(NULL, FALSE, FALSE, NULL);

		const size_t buffer_size = 50;
		{
			DIPROPDWORD dipdw;
			dipdw.diph.dwSize = sizeof(DIPROPDWORD);
			dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
			dipdw.diph.dwObj = 0;
			dipdw.diph.dwHow = DIPH_DEVICE;
			dipdw.dwData = buffer_size;

			if (FAILED(dev->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
				throw "Couldn't set buffer size";
		}

		if (FAILED(dev->SetEventNotification(ev)))
			throw "Couldn't set event";

		if (FAILED(dev->Acquire()))
			throw "Failed to acquire";

		DIDEVICEOBJECTDATA buffer[buffer_size];
	
		while (WaitForSingleObject(ev, INFINITE) != WAIT_FAILED)
		{
			DWORD items = buffer_size;
			HRESULT hr;
			if (FAILED(hr = dev->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), buffer, &items, 0)))
				throw "Couldn't get data";
			for (size_t i = 0; i < items; ++i)
				if (buffer[i].dwData)
					std::cout << buffer[i].dwData << ", " << buffer[i].dwOfs << std::endl;
		}
		return 0;

	}
	catch (const char * c)
	{
		std::cout << "failure: " << c << std::endl;
	}
	catch (HRESULT hr)
	{
		std::cout << "failureno: " << hr << std::endl;
	}
	catch (...)
	{
		std::cout << "general failure" << std::endl;
	}

	return 7;
}