static void joy_polldev(LPDIRECTINPUTDEVICE8A iface) { struct pollfd plfd; struct js_event jse; JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); TRACE("(%p)\n", This); if (This->joyfd==-1) { WARN("no device\n"); return; } while (1) { LONG value; int inst_id = -1; plfd.fd = This->joyfd; plfd.events = POLLIN; if (poll(&plfd,1,0) != 1) return; /* we have one event, so we can read */ if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) { return; } TRACE("js_event: type 0x%x, number %d, value %d\n", jse.type,jse.number,jse.value); if (jse.type & JS_EVENT_BUTTON) { if (jse.number >= This->generic.devcaps.dwButtons) return; inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON; This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00; } else if (jse.type & JS_EVENT_AXIS) { int number = This->generic.axis_map[jse.number]; /* wine format object index */ if (number < 0) return; inst_id = number < 8 ? DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS : DIDFT_MAKEINSTANCE(number - 8) | DIDFT_POV; value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value); TRACE("changing axis %d => %d\n", jse.number, number); switch (number) { case 0: This->generic.js.lX = value; break; case 1: This->generic.js.lY = value; break; case 2: This->generic.js.lZ = value; break; case 3: This->generic.js.lRx = value; break; case 4: This->generic.js.lRy = value; break; case 5: This->generic.js.lRz = value; break; case 6: This->generic.js.rglSlider[0] = value; break; case 7: This->generic.js.rglSlider[1] = value; break; case 8: case 9: case 10: case 11: { int idx = number - 8; if (jse.number % 2) This->povs[idx].y = jse.value; else This->povs[idx].x = jse.value; This->generic.js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]); break; } default: WARN("axis %d not supported\n", number); } } if (inst_id >= 0) queue_event(iface, inst_id, value, jse.time, This->generic.base.dinput->evsequence++); } }
static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) { JoystickImpl *device = impl_from_IDirectInputDevice8A(iface); IOHIDElementRef tIOHIDTopElementRef; IOHIDDeviceRef tIOHIDDeviceRef; CFArrayRef gElementCFArrayRef = device->elementCFArrayRef; TRACE("polling device %i\n",device->id); if (!gCollections) return; tIOHIDTopElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gCollections, device->id); tIOHIDDeviceRef = IOHIDElementGetDevice(tIOHIDTopElementRef); if (!tIOHIDDeviceRef) return; if (gElementCFArrayRef) { int button_idx = 0; int pov_idx = 0; int slider_idx = 0; int inst_id; CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef ); for ( idx = 0; idx < cnt; idx++ ) { IOHIDValueRef valueRef; int val, oldVal, newVal; IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx ); int eleType = IOHIDElementGetType( tIOHIDElementRef ); switch(eleType) { case kIOHIDElementTypeInput_Button: if(button_idx < 128) { IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); newVal = val ? 0x80 : 0x0; oldVal = device->generic.js.rgbButtons[button_idx]; device->generic.js.rgbButtons[button_idx] = newVal; if (oldVal != newVal) { inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); } button_idx ++; } break; case kIOHIDElementTypeInput_Misc: { uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef ); switch(usage) { case kHIDUsage_GD_Hatswitch: { IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); oldVal = device->generic.js.rgdwPOV[pov_idx]; if (val >= 8) newVal = -1; else newVal = val * 4500; device->generic.js.rgdwPOV[pov_idx] = newVal; if (oldVal != newVal) { inst_id = DIDFT_MAKEINSTANCE(pov_idx) | DIDFT_POV; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); } pov_idx ++; break; } case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: case kHIDUsage_GD_Slider: { int wine_obj = -1; IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); newVal = joystick_map_axis(&device->generic.props[idx], val); switch (usage) { case kHIDUsage_GD_X: wine_obj = 0; oldVal = device->generic.js.lX; device->generic.js.lX = newVal; break; case kHIDUsage_GD_Y: wine_obj = 1; oldVal = device->generic.js.lY; device->generic.js.lY = newVal; break; case kHIDUsage_GD_Z: wine_obj = 2; oldVal = device->generic.js.lZ; device->generic.js.lZ = newVal; break; case kHIDUsage_GD_Rx: wine_obj = 3; oldVal = device->generic.js.lRx; device->generic.js.lRx = newVal; break; case kHIDUsage_GD_Ry: wine_obj = 4; oldVal = device->generic.js.lRy; device->generic.js.lRy = newVal; break; case kHIDUsage_GD_Rz: wine_obj = 5; oldVal = device->generic.js.lRz; device->generic.js.lRz = newVal; break; case kHIDUsage_GD_Slider: wine_obj = 6 + slider_idx; oldVal = device->generic.js.rglSlider[slider_idx]; device->generic.js.rglSlider[slider_idx] = newVal; slider_idx ++; break; } if ((wine_obj != -1) && (oldVal != newVal)) { inst_id = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); } break; } default: FIXME("unhandled usage %i\n",usage); } break; } default: FIXME("Unhandled type %i\n",eleType); } } } }
/* convert wine format offset to user format object index */ static void joy_polldev(JoystickImpl *This) { struct pollfd plfd; struct input_event ie; if (This->joyfd==-1) return; while (1) { LONG value = 0; int inst_id = -1; plfd.fd = This->joyfd; plfd.events = POLLIN; if (poll(&plfd,1,0) != 1) return; /* we have one event, so we can read */ if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie))) return; TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value); switch (ie.type) { case EV_KEY: /* button */ { int btn = This->buttons[ie.code]; TRACE("(%p) %d -> %d\n", This, ie.code, btn); if (btn & 0x80) { btn &= 0x7F; inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON; This->js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00; } break; } case EV_ABS: { int axis = This->axes[ie.code]; if (axis==-1) { break; } inst_id = DIDFT_MAKEINSTANCE(axis) | (ie.code < ABS_HAT0X ? DIDFT_ABSAXIS : DIDFT_POV); value = joystick_map_axis(&This->props[id_to_object(This->base.data_format.wine_df, inst_id)], ie.value); switch (ie.code) { case ABS_X: This->js.lX = value; break; case ABS_Y: This->js.lY = value; break; case ABS_Z: This->js.lZ = value; break; case ABS_RX: This->js.lRx = value; break; case ABS_RY: This->js.lRy = value; break; case ABS_RZ: This->js.lRz = value; break; case ABS_THROTTLE: This->js.rglSlider[0] = value; break; case ABS_RUDDER: This->js.rglSlider[1] = value; break; case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y: case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y: { int idx = (ie.code - ABS_HAT0X) / 2; if (ie.code % 2) This->povs[idx].y = ie.value; else This->povs[idx].x = ie.value; This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]); break; } default: FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value); } break; } #ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION case EV_FF_STATUS: This->ff_state = ie.value; break; #endif #ifdef EV_SYN case EV_SYN: /* there is nothing to do */ break; #endif default: FIXME("joystick cannot handle type %d event (code %d)\n",ie.type,ie.code); break; } if (inst_id >= 0) queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id), value, ie.time.tv_usec, This->base.dinput->evsequence++); } }
static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) { JoystickImpl *device = (JoystickImpl*)iface; IOHIDElementRef tIOHIDTopElementRef; IOHIDDeviceRef tIOHIDDeviceRef; CFArrayRef gElementCFArrayRef = device->elementCFArrayRef; TRACE("polling device %i\n",device->id); if (!gCollections) return; tIOHIDTopElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gCollections, device->id); tIOHIDDeviceRef = IOHIDElementGetDevice(tIOHIDTopElementRef); if (!tIOHIDDeviceRef) return; if (gElementCFArrayRef) { int button_idx = 0; int pov_idx = 0; int slider_idx = 0; CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef ); for ( idx = 0; idx < cnt; idx++ ) { IOHIDValueRef valueRef; int val; IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx ); int eleType = IOHIDElementGetType( tIOHIDElementRef ); switch(eleType) { case kIOHIDElementTypeInput_Button: if(button_idx < 128) { IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); device->generic.js.rgbButtons[button_idx] = val ? 0x80 : 0x00; button_idx ++; } break; case kIOHIDElementTypeInput_Misc: { uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef ); switch(usage) { case kHIDUsage_GD_Hatswitch: { IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); if (val >= 8) device->generic.js.rgdwPOV[pov_idx] = -1; else device->generic.js.rgdwPOV[pov_idx] = val * 4500; pov_idx ++; break; } case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: case kHIDUsage_GD_Slider: { IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef); val = IOHIDValueGetIntegerValue(valueRef); switch (usage) { case kHIDUsage_GD_X: device->generic.js.lX = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Y: device->generic.js.lY = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Z: device->generic.js.lZ = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Rx: device->generic.js.lRx = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Ry: device->generic.js.lRy = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Rz: device->generic.js.lRz = joystick_map_axis(&device->generic.props[idx], val); break; case kHIDUsage_GD_Slider: device->generic.js.rglSlider[slider_idx] = joystick_map_axis(&device->generic.props[idx], val); slider_idx ++; break; } break; } default: FIXME("unhandled usage %i\n",usage); } break; } default: FIXME("Unhandled type %i\n",eleType); } } } }