/* 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++); } }
/* low-level mouse hook */ static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam ) { MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam; SysMouseImpl* This = (SysMouseImpl*) iface; DWORD dwCoop; int wdata = 0, inst_id = -1; TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y); EnterCriticalSection(&This->base.crit); dwCoop = This->base.dwCoopLevel; switch(wparam) { case WM_MOUSEMOVE: { POINT pt, pt1; GetCursorPos(&pt); This->m_state.lX += pt.x = hook->pt.x - pt.x; This->m_state.lY += pt.y = hook->pt.y - pt.y; if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) { pt1.x = This->m_state.lX; pt1.y = This->m_state.lY; } else pt1 = pt; if (pt.x) { inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS; wdata = pt1.x; } if (pt.y) { /* Already have X, need to queue it */ if (inst_id != -1) queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id), wdata, GetCurrentTime(), This->base.dinput->evsequence); inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS; wdata = pt1.y; } This->need_warp = (pt.x || pt.y) && dwCoop & DISCL_EXCLUSIVE; break; } case WM_MOUSEWHEEL: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS; This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData); break; case WM_LBUTTONDOWN: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[0] = wdata = 0x80; break; case WM_LBUTTONUP: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[0] = wdata = 0x00; break; case WM_RBUTTONDOWN: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[1] = wdata = 0x80; break; case WM_RBUTTONUP: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[1] = wdata = 0x00; break; case WM_MBUTTONDOWN: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[2] = wdata = 0x80; break; case WM_MBUTTONUP: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[2] = wdata = 0x00; break; case WM_XBUTTONDOWN: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80; break; case WM_XBUTTONUP: inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON; This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00; break; } if (inst_id != -1) { _dump_mouse_state(&This->m_state); queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id), wdata, GetCurrentTime(), This->base.dinput->evsequence++); } LeaveCriticalSection(&This->base.crit); }
static void joy_polldev(JoystickImpl *This) { struct pollfd plfd; struct js_event jse; 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->devcaps.dwButtons) return; inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON; This->js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00; } else if (jse.type & JS_EVENT_AXIS) { int number = This->axis_map[jse.number]; /* wine format object index */ if (number < 0) return; inst_id = DIDFT_MAKEINSTANCE(number) | (number < 8 ? DIDFT_ABSAXIS : DIDFT_POV); value = joystick_map_axis(&This->props[id_to_object(This->base.data_format.wine_df, inst_id)], jse.value); TRACE("changing axis %d => %d\n", jse.number, number); switch (number) { case 0: This->js.lX = value; break; case 1: This->js.lY = value; break; case 2: This->js.lZ = value; break; case 3: This->js.lRx = value; break; case 4: This->js.lRy = value; break; case 5: This->js.lRz = value; break; case 6: This->js.rglSlider[0] = value; break; case 7: This->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->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((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id), value, jse.time, This->base.dinput->evsequence++); } }