淺析linux中滑鼠資料讀取

來源:互聯網
上載者:User
$ ll /dev/input/micecrw-rw---- 1 root root 13, 63 2009-07-09 15:54 /dev/input/mice讀/dev/input/mice裝置節點的源碼如下: #include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h>
#include <string.h>

//以下代碼來自libminigui-1.6.10/src/ial/native/native.c
//需要在文本控制台下運行,才能擷取到資料,在ubuntu 8.10 GNOME介面只能收到1個位元組資料0xfa
//InitIAL==>__mg_cur_input = inputs{"console", InitNativeInput, TermNativeInput},
//mousedev = mousedev_IMPS2;
//input->update_mouse = mouse_update;

/* Mouse button bits */
#define WHEEL_UP 0x10
#define WHEEL_DOWN 0x08
#define BUTTON_L 0x04
#define BUTTON_M 0x02
#define BUTTON_R 0x01
#define SCALE 3 /* default scaling factor for acceleration */
#define THRESH 5 /* default threshhold for acceleration */

static int xpos; /* current x position of mouse */
static int ypos; /* current y position of mouse */
static int minx; /* minimum allowed x position */
static int maxx; /* maximum allowed x position */
static int miny; /* minimum allowed y position */
static int maxy; /* maximum allowed y position */
static int buttons; /* current state of buttons */
static int scale = SCALE; /* acceleration scale factor */
static int thresh = THRESH;/* acceleration threshhold */
static int mouse_update(int dx, int dy, int dz);
static int IMPS2_Read (int *dx, int *dy, int *dz, int *bp);
static void mouse_setposition (int newx, int newy);
static void mouse_setrange (int newminx, int newminy, int newmaxx, int newmaxy);
int mouse_fd;

int main(void)
{
    int dx,dy,dz;
    static unsigned char imps2_param [] = {243,200,243,100,243,80};//,242};

    // 來自vnc4的xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c==> PROT_IMPS2
    const char *mdev="/dev/input/mice";
    mouse_fd = open (mdev, O_RDWR); // | O_NONBLOCK);

    if (mouse_fd < 0) {
        perror("open mouse error");
        mouse_fd = open (mdev, O_RDONLY); // | O_NONBLOCK);
        if (mouse_fd < 0)
            return -1;
    } else {
        write (mouse_fd, imps2_param, sizeof (imps2_param)); // 初始化序列, 這樣可以讀取4個位元組資料
        // 0x80用來表示滾輪向上還是向下滾動
        // 0xa0表示滾輪向上滾動的同時中鍵按下
        printf("imps2_param ok!\n");
    }

    mouse_setrange(0, 0, 1024, 768);
    for (;;) {
        IMPS2_Read(&dx, &dy, &dz, &buttons);
        mouse_update(dx, dy, dz);
        mouse_setposition(xpos, ypos);
        printf("[%04d,%04d,0x%04x]\n", xpos, ypos, buttons);
    }
    return 0;
}

static int IMPS2_Read (int *dx, int *dy, int *dz, int *bp)
{
    static unsigned char buf[5];
    static int buttons[7] = { 0, 1, 3, 0, 2, 0, 0}; // 1左鍵,2中鍵,3右鍵
    static int nbytes;
    int n;

    while ((n = read (mouse_fd, &buf [nbytes], 4 - nbytes))) {
        if (n < 0) {
            if (errno == EINTR)
                continue;
            else
                return -1;
        }

        nbytes += n;
        if (nbytes == 4) {
            int wheel;
            // printf("[luther.gliethttp]: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
            if ((buf[0] & 0xc0) != 0) {
                buf[0] = buf[1];
                buf[1] = buf[2];
                buf[2] = buf[3];
                nbytes = 3;
                return -1;
            }
            /* FORM XFree86 4.0.1 */
            *bp = buttons[(buf[0] & 0x07)];
            *dx = (buf[0] & 0x10) ? buf[1] - 256 : buf[1];
            *dy = (buf[0] & 0x20) ? -(buf[2] - 256) : -buf[2];
            /* Is a wheel event? */
            if ((wheel = buf[3]) != 0) {
                if(wheel > 0x7f) {
                    *bp |= WHEEL_UP;
                }
                else {
                    *bp |= WHEEL_DOWN;
                }
            }
            *dz = 0;
            nbytes = 0;
            return 1;
        }
    }
    return 0;
}

static int mouse_update(int dx, int dy, int dz)
{
    int r;
    int sign;
    sign = 1;
    if (dx < 0) {
        sign = -1;
        dx = -dx;
    }
    if (dx > thresh)
        dx = thresh + (dx - thresh) * scale;
    dx *= sign;
    xpos += dx;
    if( xpos < minx )
        xpos = minx;
    if( xpos > maxx )
        xpos = maxx;
    sign = 1;
    if (dy < 0) {
        sign = -1;
        dy = -dy;
    }
    if (dy > thresh)
        dy = thresh + (dy - thresh) * scale;
    dy *= sign;
    ypos += dy;
    if ( ypos < miny )
        ypos = miny;
    if ( ypos > maxy )
        ypos = maxy;
    return 1;
}

static void mouse_setposition (int newx, int newy)
{
    if (newx < minx)
        newx = minx;
    if (newx > maxx)
        newx = maxx;
    if (newy < miny)
        newy = miny;
    if (newy > maxy)
        newy = maxy;
    if (newx == xpos && newy == ypos)
        return;
    xpos = newx;
    ypos = newy;
}

static void mouse_setrange (int newminx, int newminy, int newmaxx, int newmaxy)
{
    minx = newminx;
    miny = newminy;
    maxx = newmaxx;
    maxy = newmaxy;
    mouse_setposition ((newminx + newmaxx) / 2, (newminy + newmaxy) / 2);
}

static int mouse_getbutton (void)
{
    return buttons;
}

static void mouse_getxy (int* x, int* y)
{
    *x = xpos;
    *y = ypos;
}

來自為知筆記(Wiz)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.