/* Change cooperative level based on whether or not we are fullscreen */
void DX5_DInputReset(_THIS, int fullscreen)
{
	DWORD level;
	int i;
	HRESULT result;
	HWND topwnd;

	for ( i=0; i<MAX_INPUTS; ++i ) {
		if ( SDL_DIdev[i] != NULL ) {
			if ( fullscreen ) {
				level = inputs[i].raw_level;
			} else {
				level = inputs[i].win_level;
			}
			IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
			topwnd = GetTopLevelParent(SDL_Window);
			result = IDirectInputDevice2_SetCooperativeLevel(
					SDL_DIdev[i], topwnd, level);
			IDirectInputDevice2_Acquire(SDL_DIdev[i]);
			if ( result != DI_OK ) {
				SetDIerror(
			"DirectInputDevice::SetCooperativeLevel", result);
			}
		}
	}
	mouse_lost = 1;

	/* Flush pending input */
	DX5_CheckInput(this, 0, FALSE);
}
/* Function to scan the system for joysticks.
 * This function should set SDL_numjoysticks to the number of available
 * joysticks.  Joystick 0 should be the system default joystick.
 * It should return 0, or -1 on an unrecoverable fatal error.
 */
int
SDL_SYS_JoystickInit(void)
{
    HRESULT result;
    HINSTANCE instance;

    SYS_NumJoysticks = 0;

    result = CoInitialize(NULL);
    if (FAILED(result)) {
        SetDIerror("CoInitialize", result);
        return (-1);
    }

    result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
                              &IID_IDirectInput, (LPVOID)&dinput);

    if (FAILED(result)) {
        SetDIerror("CoCreateInstance", result);
        return (-1);
    }

    /* Because we used CoCreateInstance, we need to Initialize it, first. */
    instance = GetModuleHandle(NULL);
    if (instance == NULL) {
        SDL_SetError("GetModuleHandle() failed with error code %d.",
                     GetLastError());
        return (-1);
    }
    result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION);

    if (FAILED(result)) {
        SetDIerror("IDirectInput::Initialize", result);
        return (-1);
    }

    /* Look for joysticks, wheels, head trackers, gamepads, etc.. */
    result = IDirectInput_EnumDevices(dinput,
                                      DIDEVTYPE_JOYSTICK,
                                      EnumJoysticksCallback,
                                      NULL, DIEDFL_ATTACHEDONLY);

    return SYS_NumJoysticks;
}
Example #3
0
int
SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
{
    HRESULT result;
    LPDIRECTINPUTDEVICE8 device;
    DIPROPDWORD dipdw;

    joystick->hwdata->buffered = SDL_TRUE;
    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);

    SDL_zero(dipdw);
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);

    result =
        IDirectInput8_CreateDevice(dinput,
        &(joystickdevice->dxdevice.guidInstance), &device, NULL);
    if (FAILED(result)) {
        return SetDIerror("IDirectInput::CreateDevice", result);
    }

    /* Now get the IDirectInputDevice8 interface, instead. */
    result = IDirectInputDevice8_QueryInterface(device,
        &IID_IDirectInputDevice8,
        (LPVOID *)& joystick->
        hwdata->InputDevice);
    /* We are done with this object.  Use the stored one from now on. */
    IDirectInputDevice8_Release(device);

    if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::QueryInterface", result);
    }

    /* Acquire shared access. Exclusive access is required for forces,
    * though. */
    result =
        IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
        InputDevice, SDL_HelperWindow,
        DISCL_EXCLUSIVE |
        DISCL_BACKGROUND);
    if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result);
    }

    /* Use the extended data structure: DIJOYSTATE2. */
    result =
        IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
        &SDL_c_dfDIJoystick2);
    if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::SetDataFormat", result);
    }

    /* Get device capabilities */
    result =
        IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
        &joystick->hwdata->Capabilities);
    if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::GetCapabilities", result);
    }

    /* Force capable? */
    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {

        result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
        if (FAILED(result)) {
            return SetDIerror("IDirectInputDevice8::Acquire", result);
        }

        /* reset all actuators. */
        result =
            IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
            InputDevice,
            DISFFC_RESET);

        /* Not necessarily supported, ignore if not supported.
        if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result);
        }
        */

        result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);

        if (FAILED(result)) {
            return SetDIerror("IDirectInputDevice8::Unacquire", result);
        }

        /* Turn on auto-centering for a ForceFeedback device (until told
        * otherwise). */
        dipdw.diph.dwObj = 0;
        dipdw.diph.dwHow = DIPH_DEVICE;
        dipdw.dwData = DIPROPAUTOCENTER_ON;

        result =
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
            DIPROP_AUTOCENTER, &dipdw.diph);

        /* Not necessarily supported, ignore if not supported.
        if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::SetProperty", result);
        }
        */
    }

    /* What buttons and axes does it have? */
    IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
        EnumDevObjectsCallback, joystick,
        DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);

    /* Reorder the input objects. Some devices do not report the X axis as
    * the first axis, for example. */
    SortDevObjects(joystick);

    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = INPUT_QSIZE;

    /* Set the buffer size */
    result =
        IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
        DIPROP_BUFFERSIZE, &dipdw.diph);

    if (result == DI_POLLEDDEVICE) {
        /* This device doesn't support buffering, so we're forced
         * to use less reliable polling. */
        joystick->hwdata->buffered = SDL_FALSE;
    } else if (FAILED(result)) {
        return SetDIerror("IDirectInputDevice8::SetProperty", result);
    }
    return 0;
}
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
{
	int i;
	Sint16 xrel, yrel;
	Uint8 state;
	Uint8 button;
	DWORD timestamp = 0;

	
	if (SDL_PublicSurface == NULL) {
		return;
	}

	
	if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
		mouse_lost = 1;
		ClipCursor(NULL);
	} else {
		
		if ( mouse_lost ) {
			POINT mouse_pos;
			Uint8 old_state;
			Uint8 new_state;

			
			GetCursorPos(&mouse_pos);
			ScreenToClient(SDL_Window, &mouse_pos);
			post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);

			
			old_state = SDL_GetMouseState(NULL, NULL);
			new_state = 0;
			{ 
	#if DIRECTINPUT_VERSION >= 0x700
				DIMOUSESTATE2 distate;
	#else
				DIMOUSESTATE distate;
	#endif
				HRESULT result;

				result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
							sizeof(distate), &distate);
				if ( result != DI_OK ) {
					
					SetDIerror(
					"IDirectInputDevice2::GetDeviceState", result);
					return;
				}
				for ( i=3; i>=0; --i ) {
					if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
						new_state |= 0x01;
					}
					new_state <<= 1;
				}
			}
			for ( i=0; i<8; ++i ) {
				if ( (old_state&0x01) != (new_state&0x01) ) {
					button = (Uint8)(i+1);
					
					switch ( button ) {
						case 2: button = SDL_BUTTON_RIGHT; break;
						case 3: button = SDL_BUTTON_MIDDLE; break;
						case 4: button = SDL_BUTTON_X1; break;
						case 5: button = SDL_BUTTON_X2; break;
						default: break;
					}
					if ( new_state & 0x01 ) {
						
						if ( ++mouse_pressed > 0 ) {
							SetCapture(SDL_Window);
						}
						state = SDL_PRESSED;
					} else {
						
						if ( --mouse_pressed <= 0 ) {
							ReleaseCapture();
							mouse_pressed = 0;
						}
						state = SDL_RELEASED;
					}
					if ( mouse_buttons_swapped ) {
						if ( button == 1 ) button = 3;
						else
						if ( button == 3 ) button = 1;
					}
					posted = SDL_PrivateMouseButton(state, button,
										0, 0);
				}
				old_state >>= 1;
				new_state >>= 1;
			}
			mouse_lost = 0;
			return;
		}

		
		xrel = 0;
		yrel = 0;
		for ( i=0; i<(int)numevents; ++i ) {
			switch (ptrbuf[i].dwOfs) {
				case DIMOFS_X:
					if ( timestamp != ptrbuf[i].dwTimeStamp ) {
						if ( xrel || yrel ) {
							post_mouse_motion(1, xrel, yrel);
							xrel = 0;
							yrel = 0;
						}
						timestamp = ptrbuf[i].dwTimeStamp;
					}
					xrel += (Sint16)ptrbuf[i].dwData;
					break;
				case DIMOFS_Y:
					if ( timestamp != ptrbuf[i].dwTimeStamp ) {
						if ( xrel || yrel ) {
							post_mouse_motion(1, xrel, yrel);
							xrel = 0;
							yrel = 0;
						}
						timestamp = ptrbuf[i].dwTimeStamp;
					}
					yrel += (Sint16)ptrbuf[i].dwData;
					break;
				case DIMOFS_Z:
					if ( xrel || yrel ) {
						post_mouse_motion(1, xrel, yrel);
						xrel = 0;
						yrel = 0;
					}
					timestamp = 0;
					if((int)ptrbuf[i].dwData > 0)
						button = SDL_BUTTON_WHEELUP;
					else
						button = SDL_BUTTON_WHEELDOWN;
					posted = SDL_PrivateMouseButton(
							SDL_PRESSED, button, 0, 0);
					posted |= SDL_PrivateMouseButton(
							SDL_RELEASED, button, 0, 0);
					break;
				case DIMOFS_BUTTON0:
				case DIMOFS_BUTTON1:
				case DIMOFS_BUTTON2:
				case DIMOFS_BUTTON3:
	#if DIRECTINPUT_VERSION >= 0x700
				case DIMOFS_BUTTON4:
				case DIMOFS_BUTTON5:
				case DIMOFS_BUTTON6:
				case DIMOFS_BUTTON7:
	#endif
					if ( xrel || yrel ) {
						post_mouse_motion(1, xrel, yrel);
						xrel = 0;
						yrel = 0;
					}
					timestamp = 0;
					button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
					
					switch ( button ) {
						case 2: button = SDL_BUTTON_RIGHT; break;
						case 3: button = SDL_BUTTON_MIDDLE; break;
						case 4: button = SDL_BUTTON_X1; break;
						case 5: button = SDL_BUTTON_X2; break;
						default: break;
					}
					if ( ptrbuf[i].dwData & 0x80 ) {
						
						if ( ++mouse_pressed > 0 ) {
							SetCapture(SDL_Window);
						}
						state = SDL_PRESSED;
					} else {
						
						if ( --mouse_pressed <= 0 ) {
							ReleaseCapture();
							mouse_pressed = 0;
						}
						state = SDL_RELEASED;
					}
					if ( mouse_buttons_swapped ) {
						if ( button == 1 ) button = 3;
						else
						if ( button == 3 ) button = 1;
					}
					posted = SDL_PrivateMouseButton(state, button,
										0, 0);
					break;
			}
		}
		if ( xrel || yrel ) {
			post_mouse_motion(1, xrel, yrel);
		}
	}
}
static int DX5_DInputInit(_THIS)
{
	int         i;
	LPDIRECTINPUTDEVICE device;
	HRESULT     result;
	DIPROPDWORD dipdw;
	HWND        topwnd;

	
	result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
							&dinput, NULL);
	if ( result != DI_OK ) {
		SetDIerror("DirectInputCreate", result);
		return(-1);
	}

	
	SDL_DIndev = 0;
	for ( i=0; inputs[i].name; ++i ) {
		
		result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
								&device, NULL);
		if ( result != DI_OK ) {
			SetDIerror("DirectInput::CreateDevice", result);
			return(-1);
		}
		result = IDirectInputDevice_QueryInterface(device,
			&IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
		IDirectInputDevice_Release(device);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::QueryInterface", result);
			return(-1);
		}
		topwnd =  GetTopLevelParent(SDL_Window);
		result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
					topwnd, inputs[i].win_level);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetCooperativeLevel",
									result);
			return(-1);
		}
		result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
							inputs[i].format);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetDataFormat", result);
			return(-1);
		}

		
		SDL_memset(&dipdw, 0, sizeof(dipdw));
		dipdw.diph.dwSize = sizeof(dipdw);
		dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
		dipdw.diph.dwObj = 0;
		dipdw.diph.dwHow = DIPH_DEVICE;
		dipdw.dwData = INPUT_QSIZE;
		result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
						DIPROP_BUFFERSIZE, &dipdw.diph);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetProperty", result);
			return(-1);
		}

		
		SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
		if ( SDL_DIevt[i] == NULL ) {
			SDL_SetError("Couldn't create DirectInput event");
			return(-1);
		}
		result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
								SDL_DIevt[i]);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetEventNotification",
									result);
			return(-1);
		}
		SDL_DIfun[i] = inputs[i].fun;

		
		IDirectInputDevice2_Acquire(SDL_DIdev[i]);

		
		++SDL_DIndev;
	}
	mouse_pressed = 0;
	mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);

	
	return(0);
}
/* Function to open a joystick for use.
   The joystick to open is specified by the index field of the joystick.
   This should fill the nbuttons and naxes fields of the joystick structure.
   It returns 0, or -1 if there is an error.
 */
int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
{
    HRESULT result;
    LPDIRECTINPUTDEVICE device;
    DIPROPDWORD dipdw;

    SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD));
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);


    /* allocate memory for system specific hardware data */
    joystick->hwdata =
        (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
    if (joystick->hwdata == NULL) {
        SDL_OutOfMemory();
        return (-1);
    }
    SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata));
    joystick->hwdata->buffered = 1;
    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);

    result =
        IDirectInput_CreateDevice(dinput,
                                  &SYS_Joystick[joystick->index].
                                  guidInstance, &device, NULL);
    if (FAILED(result)) {
        SetDIerror("IDirectInput::CreateDevice", result);
        return (-1);
    }

    /* Now get the IDirectInputDevice2 interface, instead. */
    result = IDirectInputDevice_QueryInterface(device,
                                               &IID_IDirectInputDevice2,
                                               (LPVOID *) & joystick->
                                               hwdata->InputDevice);
    /* We are done with this object.  Use the stored one from now on. */
    IDirectInputDevice_Release(device);

    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice::QueryInterface", result);
        return (-1);
    }

    /* Aquire shared access. Exclusive access is required for forces,
     * though. */
    result =
        IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata->
                                                InputDevice, SDL_HelperWindow,
                                                DISCL_EXCLUSIVE |
                                                DISCL_BACKGROUND);
    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result);
        return (-1);
    }

    /* Use the extended data structure: DIJOYSTATE2. */
    result =
        IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice,
                                          &c_dfDIJoystick2);
    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetDataFormat", result);
        return (-1);
    }

    /* Get device capabilities */
    result =
        IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice,
                                            &joystick->hwdata->Capabilities);

    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::GetCapabilities", result);
        return (-1);
    }

    /* Force capable? */
    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {

        result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::Acquire", result);
            return (-1);
        }

        /* reset all accuators. */
        result =
            IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata->
                                                         InputDevice,
                                                         DISFFC_RESET);

        /* Not necessarily supported, ignore if not supported.
        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand",
                       result);
            return (-1);
        }
        */

        result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::Unacquire", result);
            return (-1);
        }

        /* Turn on auto-centering for a ForceFeedback device (until told
         * otherwise). */
        dipdw.diph.dwObj = 0;
        dipdw.diph.dwHow = DIPH_DEVICE;
        dipdw.dwData = DIPROPAUTOCENTER_ON;

        result =
            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
                                            DIPROP_AUTOCENTER, &dipdw.diph);

        /* Not necessarily supported, ignore if not supported.
        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::SetProperty", result);
            return (-1);
        }
        */
    }

    /* What buttons and axes does it have? */
    IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
                                    EnumDevObjectsCallback, joystick,
                                    DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);

    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = INPUT_QSIZE;

    /* Set the buffer size */
    result =
        IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
                                        DIPROP_BUFFERSIZE, &dipdw.diph);

    if (result == DI_POLLEDDEVICE) {
        /* This device doesn't support buffering, so we're forced
         * to use less reliable polling. */
        joystick->hwdata->buffered = 0;
    } else if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetProperty", result);
        return (-1);
    }

    return (0);
}
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
{
	int i;
	Sint16 xrel, yrel;
	Uint8 state;
	Uint8 button;
	DWORD timestamp = 0;

	/* Sanity check. Mailing list reports this being NULL unexpectedly. */
	if (SDL_PublicSurface == NULL) {
		return;
	}

	/* If we are in windowed mode, Windows is taking care of the mouse */
	if (  (SDL_PublicSurface->flags & SDL_OPENGL) ||
	     !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
		return;
	}

	/* If the mouse was lost, regain some sense of mouse state */
	if ( mouse_lost ) {
		POINT mouse_pos;
		Uint8 old_state;
		Uint8 new_state;

		/* Set ourselves up with the current cursor position */
		GetCursorPos(&mouse_pos);
		ScreenToClient(SDL_Window, &mouse_pos);
		posted = SDL_PrivateMouseMotion(0, 0,
				(Sint16)mouse_pos.x, (Sint16)mouse_pos.y);

		/* Check for mouse button changes */
		old_state = SDL_GetMouseState(NULL, NULL);
		new_state = 0;
		{ /* Get the new DirectInput button state for the mouse */
			DIMOUSESTATE distate;
			HRESULT result;

			result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
						sizeof(distate), &distate);
			if ( result != DI_OK ) {
				/* Try again next time */
				SetDIerror(
				"IDirectInputDevice2::GetDeviceState", result);
				return;
			}
			for ( i=3; i>=0; --i ) {
				if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
					new_state |= 0x01;
				}
				new_state <<= 1;
			}
		}
		for ( i=0; i<8; ++i ) {
			if ( (old_state&0x01) != (new_state&0x01) ) {
				button = (Uint8)(i+1);
				/* Button #2 on two button mice is button 3
				   (the middle button is button 2)
				 */
				if ( button == 2 ) {
					button = 3;
				} else
				if ( button == 3 ) {
					button = 2;
				}
				if ( new_state & 0x01 ) {
					/* Grab mouse so we get mouse-up */
					if ( ++mouse_pressed > 0 ) {
						SetCapture(SDL_Window);
					}
					state = SDL_PRESSED;
				} else {
					/* Release mouse after all mouse-ups */
					if ( --mouse_pressed <= 0 ) {
						ReleaseCapture();
						mouse_pressed = 0;
					}
					state = SDL_RELEASED;
				}
				if ( mouse_buttons_swapped ) {
					if ( button == 1 ) button = 3;
					else
					if ( button == 3 ) button = 1;
				}
				posted = SDL_PrivateMouseButton(state, button,
									0, 0);
			}
			old_state >>= 1;
			new_state >>= 1;
		}
		mouse_lost = 0;
		return;
	}

	/* Translate mouse messages */
	xrel = 0;
	yrel = 0;
	for ( i=0; i<(int)numevents; ++i ) {
		switch (ptrbuf[i].dwOfs) {
			case DIMOFS_X:
				if ( timestamp != ptrbuf[i].dwTimeStamp ) {
					if ( xrel || yrel ) {
						posted = SDL_PrivateMouseMotion(
								0, 1, xrel, yrel);
						xrel = 0;
						yrel = 0;
					}
					timestamp = ptrbuf[i].dwTimeStamp;
				}
				xrel += (Sint16)ptrbuf[i].dwData;
				break;
			case DIMOFS_Y:
				if ( timestamp != ptrbuf[i].dwTimeStamp ) {
					if ( xrel || yrel ) {
						posted = SDL_PrivateMouseMotion(
								0, 1, xrel, yrel);
						xrel = 0;
						yrel = 0;
					}
					timestamp = ptrbuf[i].dwTimeStamp;
				}
				yrel += (Sint16)ptrbuf[i].dwData;
				break;
			case DIMOFS_Z:
				if ( xrel || yrel ) {
					posted = SDL_PrivateMouseMotion(
							0, 1, xrel, yrel);
					xrel = 0;
					yrel = 0;
				}
				timestamp = 0;
				if((int)ptrbuf[i].dwData > 0)
					button = SDL_BUTTON_WHEELUP;
				else
					button = SDL_BUTTON_WHEELDOWN;
				posted = SDL_PrivateMouseButton(
						SDL_PRESSED, button, 0, 0);
				posted |= SDL_PrivateMouseButton(
						SDL_RELEASED, button, 0, 0);
				break;
			case DIMOFS_BUTTON0:
			case DIMOFS_BUTTON1:
			case DIMOFS_BUTTON2:
			case DIMOFS_BUTTON3:
				if ( xrel || yrel ) {
					posted = SDL_PrivateMouseMotion(
							0, 1, xrel, yrel);
					xrel = 0;
					yrel = 0;
				}
				timestamp = 0;
				button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
				/* Button #2 on two button mice is button 3
				   (the middle button is button 2)
				 */
				if ( button == 2 ) {
					button = 3;
				} else
				if ( button == 3 ) {
					button = 2;
				}
				if ( ptrbuf[i].dwData & 0x80 ) {
					/* Grab mouse so we get mouse-up */
					if ( ++mouse_pressed > 0 ) {
						SetCapture(SDL_Window);
					}
					state = SDL_PRESSED;
				} else {
					/* Release mouse after all mouse-ups */
					if ( --mouse_pressed <= 0 ) {
						ReleaseCapture();
						mouse_pressed = 0;
					}
					state = SDL_RELEASED;
				}
				if ( mouse_buttons_swapped ) {
					if ( button == 1 ) button = 3;
					else
					if ( button == 3 ) button = 1;
				}
				posted = SDL_PrivateMouseButton(state, button,
									0, 0);
				break;
		}
	}
	if ( xrel || yrel ) {
		posted = SDL_PrivateMouseMotion( 0, 1, xrel, yrel);
	}
}
Example #8
0
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
{
	int i;
	Sint16 xrel, yrel;
	Uint8 state;
	Uint8 button;
	DWORD timestamp = 0;

	/* Sanity check. Mailing list reports this being NULL unexpectedly. */
	if (SDL_PublicSurface == NULL) {
		return;
	}

	/* If the mouse was lost, regain some sense of mouse state */
	if ( mouse_lost && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
		POINT mouse_pos;
		Uint8 old_state;
		Uint8 new_state;

		/* Set ourselves up with the current cursor position */
		GetCursorPos(&mouse_pos);
		ScreenToClient(SDL_Window, &mouse_pos);
		post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);

		/* Check for mouse button changes */
		old_state = SDL_GetMouseState(NULL, NULL);
		new_state = 0;
		{ /* Get the new DirectInput button state for the mouse */
#if DIRECTINPUT_VERSION >= 0x700
			DIMOUSESTATE2 distate;
#else
			DIMOUSESTATE distate;
#endif
			HRESULT result;

			result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
						sizeof(distate), &distate);
			if ( result != DI_OK ) {
				/* Try again next time */
				SetDIerror(
				"IDirectInputDevice2::GetDeviceState", result);
				return;
			}
			for ( i=3; i>=0; --i ) {
				if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
					new_state |= 0x01;
				}
				new_state <<= 1;
			}
		}
		for ( i=0; i<8; ++i ) {
			if ( (old_state&0x01) != (new_state&0x01) ) {
				button = (Uint8)(i+1);
				/* Map DI button numbers to SDL */
				switch ( button ) {
					case 2: button = SDL_BUTTON_RIGHT; break;
					case 3: button = SDL_BUTTON_MIDDLE; break;
					case 4: button = SDL_BUTTON_X1; break;
					case 5: button = SDL_BUTTON_X2; break;
					default: break;
				}
				if ( new_state & 0x01 ) {
					/* Grab mouse so we get mouse-up */
					if ( ++mouse_pressed > 0 ) {
						SetCapture(SDL_Window);
					}
					state = SDL_PRESSED;
				} else {
					/* Release mouse after all mouse-ups */
					if ( --mouse_pressed <= 0 ) {
						ReleaseCapture();
						mouse_pressed = 0;
					}
					state = SDL_RELEASED;
				}
				if ( mouse_buttons_swapped ) {
					if ( button == 1 ) button = 3;
					else
					if ( button == 3 ) button = 1;
				}
				posted = SDL_PrivateMouseButton(state, button,
									0, 0);
			}
			old_state >>= 1;
			new_state >>= 1;
		}
		mouse_lost = 0;
		return;
	}