package linux import "unsafe" // This file is a Go version of type input_event struct { time timeval type_ uint16 code uint16 value int32 } /* * Protocol version. */ const EV_VERSION=0x010001 /* * IOCTLs (0x00 - 0x7f) */ type input_id struct { bustype uint16 vendor uint16 product uint16 version uint16 } /** * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls * @value: latest reported value for the axis. * @minimum: specifies minimum value for the axis. * @maximum: specifies maximum value for the axis. * @fuzz: specifies fuzz value that is used to filter noise from * the event stream. * @flat: values that are within this value will be discarded by * joydev interface and reported as 0 instead. * @resolution: specifies resolution for the values reported for * the axis. * * Note that input core does not clamp reported values to the * [minimum, maximum] limits, such task is left to userspace. * * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in * units per millimeter (units/mm), resolution for rotational axes * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian. */ type input_absinfo struct { value int32; minimum int32; maximum int32; fuzz int32; flat int32; resolution int32; } const INPUT_KEYMAP_BYINDEX = (1 << 0) /** * struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls * @scancode: scancode represented in machine-endian form. * @len: length of the scancode that resides in @scancode buffer. * @index: index in the keymap, may be used instead of scancode * @flags: allows to specify how kernel should handle the request. For * example, setting INPUT_KEYMAP_BYINDEX flag indicates that kernel * should perform lookup in keymap by @index instead of @scancode * @keycode: key code assigned to this scancode * * The structure is used to retrieve and modify keymap data. Users have * option of performing lookup either by @scancode itself or by @index * in keymap entry. EVIOCGKEYCODE will also return scancode or index * (depending on which element was used to perform lookup). */ type input_keymap_entry struct { flags uint8; len uint8; index uint16; keycode uint32; scancode [32]uint8; }; type input_mask struct { type_ uint32; codes_size uint32; codes_ptr uint32; }; type uint32p = [2]uint32 const sizeof_uint32p = unsafe.Sizeof(*((*uint32p)(nil))) const sizeof_int32 = unsafe.Sizeof(*((*int32)(nil))) const sizeof_uint32 = unsafe.Sizeof(*((*uint32)(nil))) const sizeof_input_id = unsafe.Sizeof(*((*input_id)(nil))) const sizeof_input_keymap_entry = unsafe.Sizeof(*((*input_keymap_entry)(nil))) const sizeof_input_absinfo = unsafe.Sizeof(*((*input_absinfo)(nil))) const sizeof_input_mask = unsafe.Sizeof(*((*input_mask)(nil))) const sizeof_ff_effect = unsafe.Sizeof(*((*ff_effect)(nil))) var EVIOCGVERSION = IOR('E', 0x01, sizeof_int32) /* get driver version */ var EVIOCGID = IOR('E', 0x02, sizeof_input_id) /* get device ID */ var EVIOCGREP = IOR('E', 0x03, sizeof_uint32p) /* get repeat settings */ var EVIOCSREP = IOW('E', 0x03, sizeof_uint32p) /* set repeat settings */ var EVIOCGKEYCODE = IOR('E', 0x04, sizeof_uint32) /* get keycode */ var EVIOCGKEYCODE_V2= IOR('E', 0x04, sizeof_input_keymap_entry) var EVIOCSKEYCODE = IOW('E', 0x04, sizeof_uint32p) /* set keycode */ var EVIOCSKEYCODE_V2= IOW('E', 0x04, sizeof_input_keymap_entry) func EVIOCGNAME(len uintptr) uint32{ return IOC(IOC_READ, 'E', 0x06, len) /* get device name */ } func EVIOCGPHYS(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x07, len) /* get physical location */ } func EVIOCGUNIQ(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x08, len) /* get unique identifier */ } func EVIOCGPROP(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x09, len) /* get device properties */ } /** * EVIOCGMTSLOTS(len uintptr) uint32 { - get MT slot values * @len: size of the data buffer in bytes * * The ioctl buffer argument should be binary equivalent to * * type input_mt_request_layout struct { * __u32 code; * __s32 values[num_slots]; * }; * * where num_slots is the (arbitrary) number of MT slots to extract. * * The ioctl size argument (len uintptr) uint32 { is the size of the buffer, which * should satisfy len = (num_slots + 1) * sizeof(__s32). If len is * too small to fit all available slots, the first num_slots are * returned. * * Before the call, code is set to the wanted ABS_MT event type. On * return, values[] is filled with the slot values for the specified * ABS_MT code. * * If the request code is not an ABS_MT value, -EINVAL is returned. */ func EVIOCGMTSLOTS(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x0a, len) } func EVIOCGKEY(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x18, len) /* get global key state */ } func EVIOCGLED(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x19, len) /* get all LEDs */ } func EVIOCGSND(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x1a, len) /* get all sounds status */ } func EVIOCGSW(len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x1b, len) /* get all switch states */ } func EVIOCGBIT(ev uint32, len uintptr) uint32 { return IOC(IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */ } func EVIOCGABS(abs uint32) uint32 { return IOR('E', 0x40 + (abs), sizeof_input_absinfo) /* get abs value/limits */ } func EVIOCSABS(abs uint32) uint32 { return IOW('E', 0xc0 + (abs), sizeof_input_absinfo) /* set abs value/limits */ } var EVIOCSFF = IOW('E', 0x80, sizeof_ff_effect) /* send a force effect to a force feedback device */ var EVIOCRMFF = IOW('E', 0x81, sizeof_int32) /* Erase a force effect */ var EVIOCGEFFECTS = IOR('E', 0x84, sizeof_int32) /* Report number of effects playable at the same time */ var EVIOCGRAB = IOW('E', 0x90, sizeof_int32) /* Grab/Release device */ var EVIOCREVOKE = IOW('E', 0x91, sizeof_int32) /* Revoke device access */ /** * EVIOCGMASK - Retrieve current event mask * * This ioctl allows user to retrieve the current event mask for specific * event type. The argument must be of type "struct input_mask" and * specifies the event type to query, the address of the receive buffer and * the size of the receive buffer. * * The event mask is a per-client mask that specifies which events are * forwarded to the client. Each event code is represented by a single bit * in the event mask. If the bit is set, the event is passed to the client * normally. Otherwise, the event is filtered and will never be queued on * the client's receive buffer. * * Event masks do not affect global state of the input device. They only * affect the file descriptor they are applied to. * * The default event mask for a client has all bits set, i.e. all events * are forwarded to the client. If the kernel is queried for an unknown * event type or if the receive buffer is larger than the number of * event codes known to the kernel, the kernel returns all zeroes for those * codes. * * At maximum, codes_size bytes are copied. * * This ioctl may fail with ENODEV in case the file is revoked, EFAULT * if the receive-buffer points to invalid memory, or EINVAL if the kernel * does not implement the ioctl. */ var EVIOCGMASK = IOR('E', 0x92, sizeof_input_mask) /* Get event-masks */ /** * EVIOCSMASK - Set event mask * * This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the * current event mask, this changes the client's event mask for a specific * type. See EVIOCGMASK for a description of event-masks and the * argument-type. * * This ioctl provides full forward compatibility. If the passed event type * is unknown to the kernel, or if the number of event codes specified in * the mask is bigger than what is known to the kernel, the ioctl is still * accepted and applied. However, any unknown codes are left untouched and * stay cleared. That means, the kernel always filters unknown codes * regardless of what the client requests. If the new mask doesn't cover * all known event-codes, all remaining codes are automatically cleared and * thus filtered. * * This ioctl may fail with ENODEV in case the file is revoked. EFAULT is * returned if the receive-buffer points to invalid memory. EINVAL is returned * if the kernel does not implement the ioctl. */ var EVIOCSMASK = IOW('E', 0x93, sizeof_input_mask) /* Set event-masks */ var EVIOCSCLOCKID = IOW('E', 0xa0, sizeof_int32) /* Set clockid to be used for timestamps */ /* * IDs. */ const ID_BUS = 0 const ID_VENDOR = 1 const ID_PRODUCT = 2 const ID_VERSION = 3 const BUS_PCI = 0x01 const BUSISAPNP = 0x02 const BUS_USB = 0x03 const BUS_HIL = 0x04 const BUS_BLUETOOTH = 0x05 const BUS_VIRTUAL = 0x06 const BUSISA = 0x10 const BUSI8042 = 0x11 const BUS_XTKBD = 0x12 const BUS_RS232 = 0x13 const BUS_GAMEPORT = 0x14 const BUS_PARPORT = 0x15 const BUS_AMIGA = 0x16 const BUS_ADB = 0x17 const BUSI2C = 0x18 const BUS_HOST = 0x19 const BUS_GSC = 0x1A const BUS_ATARI = 0x1B const BUS_SPI = 0x1C /* * MT_TOOL types */ const MT_TOOL_FINGER = 0 const MT_TOOL_PEN = 1 const MT_TOOL_PALM = 2 const MT_TOOL_MAX = 2 /* * Values describing the status of a force-feedback effect */ const FF_STATUS_STOPPED = 0x00 const FF_STATUS_PLAYING = 0x01 const FF_STATUS_MAX = 0x01 /* * Structures used in ioctls to upload effects to a device * They are pieces of a bigger structure (called ff_effect) */ /* * All duration values are expressed in ms. Values above 32767 ms (0x7fff) * should not be used and have unspecified results. */ /** * struct ff_replay - defines scheduling of the force-feedback effect * @length: duration of the effect * @delay: delay before effect should start playing */ type ff_replay struct { length uint16 delay uint16 }; /** * struct ff_trigger - defines what triggers the force-feedback effect * @button: number of the button triggering the effect * @interval: controls how soon the effect can be re-triggered */ type ff_trigger struct { button uint16 interval uint16 }; /** * struct ff_envelope - generic force-feedback effect envelope * @attack_length: duration of the attack (ms) * @attack_level: level at the beginning of the attack * @fade_length: duration of fade (ms) * @fade_level: level at the end of fade * * The @attack_level and @fade_level are absolute values; when applying * envelope force-feedback core will convert to positive/negative * value based on polarity of the default level of the effect. * Valid range for the attack and fade levels is 0x0000 - 0x7fff */ type ff_envelope struct { attack_length uint16 attack_level uint16 fade_length uint16 fade_level uint16 }; /** * struct ff_constant_effect - defines parameters of a constant force-feedback effect * @level: strength of the effect; may be negative * @envelope: envelope data */ type ff_constant_effect struct { level int16 envelope ff_envelope }; /** * struct ff_ramp_effect - defines parameters of a ramp force-feedback effect * @start_level: beginning strength of the effect; may be negative * @end_level: final strength of the effect; may be negative * @envelope: envelope data */ type ff_ramp_effect struct { start_level int16 end_level int16 envelope ff_envelope }; /** * struct ff_condition_effect - defines a spring or friction force-feedback effect * @right_saturation: maximum level when joystick moved all way to the right * @left_saturation: same for the left side * @right_coeff: controls how fast the force grows when the joystick moves * to the right * @left_coeff: same for the left side * @deadband: size of the dead zone, where no force is produced * @center: position of the dead zone */ type ff_condition_effect struct { right_saturation uint16 left_saturation uint16 right_coeff int16 left_coeff int16 deadband uint16 center int16 }; /** * struct ff_periodic_effect - defines parameters of a periodic force-feedback effect * @waveform: kind of the effect (wave) * @period: period of the wave (ms) * @magnitude: peak value * @offset: mean value of the wave (roughly) * @phase: 'horizontal' shift * @envelope: envelope data * @custom_len: number of samples (FF_CUSTOM only) * @custom_data: buffer of samples (FF_CUSTOM only) * * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP, * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined * for the time being as no driver supports it yet. * * Note: the data pointed by custom_data is copied by the driver. * You can therefore dispose of the memory after the upload/update. */ type ff_periodic_effect struct { waveform uint16 period uint16 magnitude int16 offset int16 phase uint16 envelope ff_envelope custom_len uint32 custom_data *int16; }; /** * struct ff_rumble_effect - defines parameters of a periodic force-feedback effect * @strong_magnitude: magnitude of the heavy motor * @weak_magnitude: magnitude of the light one * * Some rumble pads have two motors of different weight. Strong_magnitude * represents the magnitude of the vibration generated by the heavy one. */ type ff_rumble_effect struct { strong_magnitude uint16 weak_magnitude uint16 }; const ff_effect_union_size = unsafe.Sizeof(*((*ff_periodic_effect)(nil))) /** * struct ff_effect - defines force feedback effect * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING, * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FFINERTIA, or FF_CUSTOM) * @id: an unique id assigned to an effect * @direction: direction of the effect * @trigger: trigger conditions (struct ff_trigger) * @replay: scheduling of the effect (struct ff_replay) * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect, * ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further * defining effect parameters * * This structure is sent through ioctl from the application to the driver. * To create a new effect application should set its @id to -1; the kernel * will return assigned @id which can later be used to update or delete * this effect. * * Direction of the effect is encoded as follows: * 0 deg -> 0x0000 (down) * 90 deg -> 0x4000 (left) * 180 deg -> 0x8000 (up) * 270 deg -> 0xC000 (right) */ type ff_effect struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay // This was a union in C, somulate with a byte buffer with size of largest element u [ff_effect_union_size]byte }; type ff_effect_u_constant struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay constant ff_constant_effect }; type ff_effect_u_ramp struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay ramp ff_ramp_effect }; type ff_effect_u_periodic struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay periodic ff_periodic_effect }; type ff_effect_u_condition struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay condition [2]ff_condition_effect; /* One for each axis */ }; type ff_effect_u_rumble struct { type_ uint16 id int16 direction uint16 trigger ff_trigger replay ff_replay rumble ff_rumble_effect }; /* * Force feedback effect types */ const FF_RUMBLE = 0x50 const FF_PERIODIC = 0x51 const FF_CONSTANT = 0x52 const FF_SPRING = 0x53 const FF_FRICTION = 0x54 const FF_DAMPER = 0x55 const FFINERTIA = 0x56 const FF_RAMP = 0x57 const FF_EFFECT_MIN = FF_RUMBLE const FF_EFFECT_MAX = FF_RAMP /* * Force feedback periodic effect types */ const FF_SQUARE = 0x58 const FF_TRIANGLE = 0x59 const FF_SINE = 0x5a const FF_SAW_UP = 0x5b const FF_SAW_DOWN = 0x5c const FF_CUSTOM = 0x5d const FF_WAVEFORM_MIN = FF_SQUARE const FF_WAVEFORM_MAX = FF_CUSTOM /* * Set ff device properties */ const FF_GAIN = 0x60 const FF_AUTOCENTER = 0x61 /* * ff->playback(effect_id = FF_GAIN) is the first effect_id to * cause a collision with another ff method, in this case ff->set_gain(). * Therefore the greatest safe value for effect_id is FF_GAIN - 1, * and thus the total number of effects should never exceed FF_GAIN. */ const FF_MAX_EFFECTS = FF_GAIN const FF_MAX = 0x7f const FF_CNT = (FF_MAX+1)