⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
字号:
/*Copyright (c) 2003-2007 Ryan C. Gordon and others.http://icculus.org/manymouse/This software is provided 'as-is', without any express or implied warranty.In no event will the authors be held liable for any damages arising fromthe use of this software.Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute itfreely, subject to the following restrictions:1. The origin of this software must not be misrepresented; you must notclaim that you wrote the original software. If you use this software in aproduct, an acknowledgment in the product documentation would beappreciated but is not required.2. Altered source versions must be plainly marked as such, and must not bemisrepresented as being the original software.3. This notice may not be removed or altered from any source distribution.    Ryan C. Gordon <icculus@icculus.org>*///Support for Linux evdevs...the /dev/input/event* devices.#include "mm.h"#ifdef __linux__#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <dirent.h>#include <errno.h>#include <sys/types.h>#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/input.h>  /* evdev interface...  */#define test_bit(array, bit)    (array[bit/8] & (1<<(bit%8)))/* linux allows 32 evdev nodes currently. */#define MAX_MICE 32typedef struct{    int fd;    int min_x;    int min_y;    int max_x;    int max_y;    char name[64];} MouseStruct;static MouseStruct mice[MAX_MICE];static unsigned int available_mice = 0;static int poll_mouse(MouseStruct *mouse, ManyMouseEvent *outevent){    int unhandled = 1;    while (unhandled)  /* read until failure or valid event. */    {        struct input_event event;        int br = read(mouse->fd, &event, sizeof (event));        if (br == -1)        {            if (errno == EAGAIN)                return(0);  /* just no new data at the moment. */            /* mouse was unplugged? */            close(mouse->fd);  /* stop reading from this mouse. */            mouse->fd = -1;            outevent->type = MANYMOUSE_EVENT_DISCONNECT;            return(1);        } /* if */        if (br != sizeof (event))            return(0);  /* oh well. */        unhandled = 0;  /* will reset if necessary. */        outevent->value = event.value;        if (event.type == EV_REL)        {            outevent->type = MANYMOUSE_EVENT_RELMOTION;            if ((event.code == REL_X) || (event.code == REL_DIAL))                outevent->item = 0;            else if (event.code == REL_Y)                outevent->item = 1;            else if (event.code == REL_WHEEL)            {                outevent->type = MANYMOUSE_EVENT_SCROLL;                outevent->item = 0;            } /* else if */            else if (event.code == REL_HWHEEL)            {                outevent->type = MANYMOUSE_EVENT_SCROLL;                outevent->item = 1;            } /* else if */            else            {                unhandled = 1;            } /* else */        } /* if */        else if (event.type == EV_ABS)        {            outevent->type = MANYMOUSE_EVENT_ABSMOTION;            if (event.code == ABS_X)            {                outevent->item = 0;                outevent->minval = mouse->min_x;                outevent->maxval = mouse->max_x;            } /* if */            else if (event.code == ABS_Y)            {                outevent->item = 1;                outevent->minval = mouse->min_y;                outevent->maxval = mouse->max_y;            } /* if */            else            {                unhandled = 1;            } /* else */        } /* else if */        else if (event.type == EV_KEY)        {            outevent->type = MANYMOUSE_EVENT_BUTTON;            if ((event.code >= BTN_LEFT) && (event.code <= BTN_BACK))                outevent->item = event.code - BTN_MOUSE;            /* just in case some device uses this block of events instead... */            else if ((event.code >= BTN_MISC) && (event.code <= BTN_LEFT))                outevent->item = (event.code - BTN_MISC);            else if (event.code == BTN_TOUCH) /* tablet... */                outevent->item = 0;            else if (event.code == BTN_STYLUS) /* tablet... */                outevent->item = 1;            else if (event.code == BTN_STYLUS2) /* tablet... */                outevent->item = 2;            else            {                /*printf("unhandled mouse button: 0x%X\n", event.code);*/                unhandled = 1;            } /* else */        } /* else if */        else        {            unhandled = 1;        } /* else */    } /* while */    return(1);  /* got a valid event */} /* poll_mouse */static int init_mouse(const char *fname, int fd){    MouseStruct *mouse = &mice[available_mice];    int has_absolutes = 0;    int is_mouse = 0;    unsigned char relcaps[(REL_MAX / 8) + 1];    unsigned char abscaps[(ABS_MAX / 8) + 1];    unsigned char keycaps[(KEY_MAX / 8) + 1];    memset(relcaps, '\0', sizeof (relcaps));    memset(abscaps, '\0', sizeof (abscaps));    memset(keycaps, '\0', sizeof (keycaps));    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof (keycaps)), keycaps) == -1)        return 0;  /* gotta have some buttons!  :)  */    if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof (relcaps)), relcaps) != -1)    {        if ( (test_bit(relcaps, REL_X)) && (test_bit(relcaps, REL_Y)) )        {            if (test_bit(keycaps, BTN_MOUSE))                is_mouse = 1;        } /* if */        #if ALLOW_DIALS_TO_BE_MICE        if (test_bit(relcaps, REL_DIAL))            is_mouse = 1;  // griffin powermate?        #endif    } /* if */    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof (abscaps)), abscaps) != -1)    {        if ( (test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y)) )        {            /* might be a touchpad... */            if (test_bit(keycaps, BTN_TOUCH))            {                is_mouse = 1;  /* touchpad, touchscreen, or tablet. */                has_absolutes = 1;            } /* if */        } /* if */    } /* if */    if (!is_mouse)        return 0;    mouse->min_x = mouse->min_y = mouse->max_x = mouse->max_y = 0;    if (has_absolutes)    {        struct        {          int value;          int minimum;          int maximum;          int fuzz;          int flat;        } absinfo;        if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) == -1)            return 0;        mouse->min_x = absinfo.minimum;        mouse->max_x = absinfo.maximum;        if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) == -1)            return 0;        mouse->min_y = absinfo.minimum;        mouse->max_y = absinfo.maximum;    } /* if */    if (ioctl(fd, EVIOCGNAME(sizeof (mouse->name)), mouse->name) == -1)        snprintf(mouse->name, sizeof (mouse->name), "Unknown device");    mouse->fd = fd;    return 1;  /* we're golden. */} /* init_mouse *//* Return a file descriptor if this is really a mouse, -1 otherwise. */static int open_if_mouse(const char *fname){    struct stat statbuf;    int fd;    int devmajor, devminor;    if (stat(fname, &statbuf) == -1)        return 0;    if (S_ISCHR(statbuf.st_mode) == 0)        return 0;  /* not a character device... */    /* evdev node ids are major 13, minor 64-96. Is this safe to check? */    devmajor = (statbuf.st_rdev & 0xFF00) >> 8;    devminor = (statbuf.st_rdev & 0x00FF);    if ( (devmajor != 13) || (devminor < 64) || (devminor > 96) )        return 0;  /* not an evdev. */    if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) == -1)        return 0;    if (init_mouse(fname, fd))        return 1;    close(fd);    return 0;} /* open_if_mouse */static int linux_evdev_init(void){    DIR *dirp;    struct dirent *dent;    int i;    for (i = 0; i < MAX_MICE; i++)        mice[i].fd = -1;    dirp = opendir("/dev/input");    if (!dirp)        return -1;    while ((dent = readdir(dirp)) != NULL)    {        char fname[128];        snprintf(fname, sizeof (fname), "/dev/input/%s", dent->d_name);        if (open_if_mouse(fname))            available_mice++;    } /* while */    closedir(dirp);    return available_mice;} /* linux_evdev_init */static void linux_evdev_quit(void){    while (available_mice)    {        int fd = mice[available_mice--].fd;        if (fd != -1)            close(fd);    } /* while */} /* linux_evdev_quit */static const char *linux_evdev_name(unsigned int index){    if (index < available_mice)        return(mice[index].name);    return(NULL);} /* linux_evdev_name */static int linux_evdev_poll(ManyMouseEvent *event){    /*     * (i) is static so we iterate through all mice round-robin. This     *  prevents a chatty mouse from dominating the queue.     */    static unsigned int i = 0;    if (i >= available_mice)        i = 0;  /* handle reset condition. */    if (event != NULL)    {        while (i < available_mice)        {            MouseStruct *mouse = &mice[i];            if (mouse->fd != -1)            {                if (poll_mouse(mouse, event))                {                    event->device = i;                    return(1);                } /* if */            } /* if */            i++;        } /* while */    } /* if */    return(0);  /* no new events */} /* linux_evdev_poll */#elsestatic int linux_evdev_init(void) { return(-1); }static void linux_evdev_quit(void) {}static const char *linux_evdev_name(unsigned int index) { return(0); }static int linux_evdev_poll(ManyMouseEvent *event) { return(0); }#endif  /* defined __linux__ */ManyMouseDriver ManyMouseDriver_evdev ={    linux_evdev_init,    linux_evdev_quit,    linux_evdev_name,    linux_evdev_poll};/* end of linux_evdev.c ... */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -