/* * This file is part of the Advance project. * * Copyright (C) 2003 Andrea Mazzoleni * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * In addition, as a special exception, Andrea Mazzoleni * gives permission to link the code of this program with * the MAME library (or with modified versions of MAME that use the * same license as MAME), and distribute linked combinations including * the two. You must obey the GNU General Public License in all * respects for all of the code used other than MAME. If you modify * this file, you may extend this exception to your version of the * file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. */ #include "portable.h" #include "event.h" #include "log.h" #include static void event_key_log(int f) { unsigned char key_bitmask[KEY_MAX/8 + 1]; unsigned i; memset(key_bitmask, 0, sizeof(key_bitmask)); if (ioctl(f, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) { log_std(("event: error in ioctl(EVIOCGBIT(EV_KEY,%d))\n", (int)KEY_MAX)); return; } log_std(("event: EV_KEY:")); for(i=0;i= 0) { log_std(("[val:%d,min:%d,max:%d,fuzz:%d,flat:%d]", features[0], features[1], features[2], features[3], features[4])); } } } log_std(("\n")); } #ifdef EV_MSC static void event_msc_log(int f) { unsigned char msc_bitmask[MSC_MAX/8 + 1]; unsigned i; memset(msc_bitmask, 0, sizeof(msc_bitmask)); if (ioctl(f, EVIOCGBIT(EV_MSC, sizeof(msc_bitmask)), msc_bitmask) < 0) { log_std(("event: error in ioctl(EVIOCGBIT(EV_MSC,%d))\n", (int)MSC_MAX)); return; } log_std(("event: EV_MSC:")); for(i=0;i> 16, (version >> 8) & 0xff, version & 0xff)); } if (ioctl(f, EVIOCGID, &device_info)) { log_std(("event: error in ioctl(EVIOCGID)\n")); } else { switch (device_info[ID_BUS]) { #ifdef BUS_PCI case BUS_PCI : bus = "pci"; break; #endif #ifdef BUS_ISAPNP case BUS_ISAPNP : bus = "isapnp"; break; #endif #ifdef BUS_USB case BUS_USB : bus = "usb"; break; #endif #ifdef BUS_ISA case BUS_ISA : bus = "usa"; break; #endif #ifdef BUS_I8042 case BUS_I8042 : bus = "i8042"; break; #endif #ifdef BUS_RS232 case BUS_RS232 : bus = "rs232"; break; #endif #ifdef BUS_GAMEPORT case BUS_GAMEPORT : bus = "gameport"; break; #endif #ifdef BUS_PARPORT case BUS_PARPORT : bus = "parport"; break; #endif #ifdef BUS_AMIGA case BUS_AMIGA : bus = "amiga"; break; #endif #ifdef BUS_ADB case BUS_ADB : bus = "adb"; break; #endif #ifdef BUS_I2C case BUS_I2C : bus = "i2c"; break; #endif default: bus = "unknown"; break; } log_std(("event: device vendor:0x%04hx product:0x%04hx version:0x%04hx bus:0x%04hx (%s)\n", (unsigned)device_info[ID_VENDOR], (unsigned)device_info[ID_PRODUCT], (unsigned)device_info[ID_VERSION], (unsigned)device_info[ID_BUS], bus )); } if (ioctl(f, EVIOCGNAME(sizeof(name)), name) < 0) { log_std(("event: error in ioctl(EVIOCGNAME)\n")); } else { log_std(("event: name:\"%s\"\n", name)); } for(i=0;i= 0;++i) if (event_test_bit(feature[i], bitmask)) { return 1; } return 0; } int ABS_FEATURE[] = { #ifdef ABS_X ABS_X, #endif #ifdef ABS_Y ABS_Y, #endif #ifdef ABS_Z ABS_Z, #endif #ifdef ABS_RX ABS_RX, #endif #ifdef ABS_RY ABS_RY, #endif #ifdef ABS_RZ ABS_RZ, #endif #ifdef ABS_GAS ABS_GAS, #endif #ifdef ABS_BRAKE ABS_BRAKE, #endif #ifdef ABS_WHELL ABS_WHEEL, #endif #ifdef ABS_HAT0X ABS_HAT0X, ABS_HAT0Y, #endif #ifdef ABS_HAT1X ABS_HAT1X, ABS_HAT1Y, #endif #ifdef ABS_HAT2X ABS_HAT2X, ABS_HAT2Y, #endif #ifdef ABS_HAT3X ABS_HAT3X, ABS_HAT3Y, #endif #ifdef ABS_THROTTLE ABS_THROTTLE, #endif #ifdef ABS_RUDDER ABS_RUDDER, #endif /* ABS_MISC is used by some mouses */ -1 }; int REL_FEATURE[] = { #ifdef REL_X REL_X, #endif #ifdef REL_Y REL_Y, #endif #ifdef REL_Z REL_Z, #endif #ifdef REL_WHEEL REL_WHEEL, #endif #ifdef REL_HWHEEL REL_HWHEEL, #endif #ifdef REL_DIAL REL_DIAL, #endif /* REL_MISC is too generic */ -1 }; int KEY_FEATURE[] = { #ifdef KEY_1 KEY_1, #endif #ifdef KEY_A KEY_A, #endif -1 }; adv_bool event_is_joystick(int f, unsigned char* evtype_bitmask) { return event_test_bit_feature(f, EV_ABS, evtype_bitmask, ABS_FEATURE); } adv_bool event_is_mouse(int f, unsigned char* evtype_bitmask) { return !event_test_bit_feature(f, EV_ABS, evtype_bitmask, ABS_FEATURE) && event_test_bit_feature(f, EV_REL, evtype_bitmask, REL_FEATURE); } adv_bool event_is_keyboard(int f, unsigned char* evtype_bitmask) { return !event_test_bit_feature(f, EV_ABS, evtype_bitmask, ABS_FEATURE) && !event_test_bit_feature(f, EV_REL, evtype_bitmask, REL_FEATURE) && event_test_bit_feature(f, EV_KEY, evtype_bitmask, KEY_FEATURE); } adv_error event_read(int f, int* type, int* code, int* value) { int size; struct input_event e; size = read(f, &e, sizeof(e)); if (size == -1 && errno == EAGAIN) { /* normal exit if data is missing */ return -1; } if (size != sizeof(e)) { log_std(("ERROR:event: invalid read size %d on the event interface, errno %d (%s)\n", size, errno, strerror(errno))); return -1; } log_debug(("event: read %ld.%06ld, type %d, code %d, value %d\n", e.time.tv_sec, e.time.tv_usec, e.type, e.code, e.value)); *type = e.type; *code = e.code; *value = e.value; return 0; } adv_error event_write(int f, int type, int code, int value) { int size; struct input_event e; e.type = type; e.code = code; e.value = value; size = write(f, &e, sizeof(e)); if (size != sizeof(e)) { log_std(("ERROR:event: invalid write size %d on the event interface, errno %d (%s)\n", size, errno, strerror(errno))); return -1; } log_debug(("event: write type %d, code %d, value %d\n", e.type, e.code, e.value)); return 0; } int event_compare(const void* void_a, const void* void_b) { const struct event_location* a = (const struct event_location*)void_a; const struct event_location* b = (const struct event_location*)void_b; if (a->vendor < b->vendor) return -1; if (a->vendor > b->vendor) return 1; if (a->product < b->product) return -1; if (a->product > b->product) return 1; if (a->id < b->id) return -1; if (a->id > b->id) return 1; return 0; } unsigned event_locate(struct event_location* event_map, unsigned event_max, adv_bool* eacces) { unsigned event_mac; unsigned i; event_mac = 0; for(i=0;i