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

📄 mouse.cpp

📁 zhcon是工作在Linux控制台下的高效双字节中/日/韩(CJK)虚拟终端
💻 CPP
字号:
// vi:ts=4:shiftwidth=4:expandtab/***************************************************************************                          mouse.cpp  -  description                             -------------------    begin                : Sat Mar 2 2002    copyright            : (C) 2002 by huyong    email                : ccpaging@online.sh.cn**************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************/#include <cassert>#include "debug.h"#include "mouse.h"#include <sys/signal.h>#if defined(__FreeBSD__)Mouse* Mouse::pMouse = NULL;void Mouse::SignalProcess(int signo) {    if (Mouse::pMouse != NULL)  pMouse->Process();}#endifMouse::Mouse() {#if defined(__FreeBSD__)    Mouse::pMouse = this;#endif       mFd = -1;    mButtons = 2;    mpCon = NULL;    mTtyFd = -1;        mX1 = mY1 = 0;}Mouse::~Mouse() {    Close();#if defined(__FreeBSD__)    Mouse::pMouse = NULL;#endif}bool Mouse::Open(Console* pCon, int confd, int ttyno, int ttyfd) {    assert(pCon);    assert(ttyfd >= 0);    mpCon = pCon;    mConFd = confd;    mTtyFd = ttyfd;#ifdef HAVE_GPM_H    mConn.eventMask   = ~0;         // get everything    mConn.defaultMask = ~GPM_HARD;  // pass everything unused    mConn.minMod      = 0;          // run always    mConn.maxMod      = ~0;         // with any modifier    if (Gpm_Open(&mConn, ttyno)==-1) {      //printf("Can't open mouse connection at %d\r\n", mMouseConn.vc);      //printf("pid=%d, vc=%d\r\n",mMouseConn.pid, mMouseConn.vc);      return false;    }    mFd = gpm_fd;    //printf("pid=%d, vc=%d\r\n",mMouseConn.pid, mMouseConn.vc);    // Get mouse button, based on mev.c in gpm    Gpm_Event event;    int i=Gpm_GetSnapshot(&event);    if (-1 == i) {       printf("Warning: cannot get snapshot!\n");       printf("Maybe in xterm or before connecting?\n");       return true;    }    mButtons = i;    /*    printf("Mouse has %d buttons\n",i);    printf("Currently sits at (%d,%d)\n",event.x,event.y);    printf("The window is %d columns by %d rows\n",event.dx,event.dy);    s=Gpm_GetLibVersion(&i);    printf("The library is version \"%s\" (%i)\n",s,i);    s=Gpm_GetServerVersion(&i);    printf("The daemon is version \"%s\" (%i)\n",s,i);    printf("The current console is %d, with modifiers 0x%02x\n",        event.vc,event.modifiers);    printf("The button mask is 0x%02X\n",event.buttons);    */#elif defined(__FreeBSD__)    memset(&mMiPrev, 0, sizeof(mMiPrev));    memset(&mTV1, 0, sizeof(mTV1));    memset(&mTV2, 0, sizeof(mTV2));    mClicks = 0;    struct mouse_info mi;    mi.operation = MOUSE_MODE;    mi.u.mode.signal = SIGUSR2;    if (ioctl(mConFd, CONS_MOUSECTL, &mi) < 0) {        //err(1, "CONS_MOUSECTL");        return false;    }    signal(SIGUSR2, Mouse::SignalProcess);#endif    return true;}void Mouse::Close() {#ifdef HAVE_GPM_H    if (mFd <= 0)        return;    while (Gpm_Close()); // close all mouse stack    mFd = -1;#elif defined(__FreeBSD__)    signal(SIGUSR2, SIG_DFL);#endif}enum MouseType {    MOUSE_MOVE = 1,    MOUSE_DRAG = 2,    MOUSE_DOWN = 4,    MOUSE_UP = 8};#define MOUSE_LEFT     4#define MOUSE_MIDDLE   2#define MOUSE_RIGHT        1// based on function do_selection in gpm.c#define DEF_PTRDRAG          1    /* double or triple click */#define GET_TIME(tv)       (gettimeofday(&tv, (struct timezone *)NULL))#define DIF_TIME(t1, t2)   ((t2.tv_sec  - t1.tv_sec) * 1000 + \                           (t2.tv_usec - t1.tv_usec) / 1000)#define DEF_TIME           250 // time interval (ms) for multiple clicksvoid Mouse::Process() {    assert(mpCon);    int maxX, maxY;    mpCon->GetVtSize(maxX, maxY);   #ifdef HAVE_GPM_H    if (mFd <= 0)        return;    Gpm_Event event;    if (Gpm_GetEvent(&event) <= 0)        return;    mX2 = event.x - 1;    mY2 = event.y - 1;    switch(GPM_BARE_EVENTS(event.type)) {        case GPM_MOVE:            if (mX2 < 0)                mX2 = 0;            else if (mX2 > maxX - 1)                mX2 = maxX - 1;            else;            if (mY2 < 0)                mY2 = 0;            else if (mY2 > maxY - 1)                mY2 = maxY - 1;            else;            mpCon->SelCopy(mX2, mY2, mX2, mY2,3); /* just highlight pointer */            return;        case GPM_DRAG:            if (event.buttons==GPM_B_LEFT) {                if (event.margin) { /* fix margins */                    switch(event.margin) {                        case GPM_TOP:                            mX2 = 0;                            mY2++;                            break;                        case GPM_BOT:                            mX2 = maxX - 1;                            mY2--;                            break;                        case GPM_RGT:                            mX2--;                            break;                        case GPM_LFT:                            if (mY2 <= mY1)                               mX2++;                            else {                               mX2 = maxX - 1;                               mY2--;                            }                            break;                    }                }                mpCon->SelCopy(mX1, mY1, mX2, mY2, event.clicks);                if (event.clicks >= DEF_PTRDRAG && !event.margin) /* pointer */                    mpCon->SelCopy(mX2, mY2, mX2, mY2, 3);            } /* if */            return;        case GPM_DOWN:            switch (event.buttons) {                case GPM_B_LEFT:                    mX1 = mX2;                    mY1 = mY2;                    mpCon->SelCopy(mX1, mY1, mX2, mY2, event.clicks);  /* start selection */                    return;                case GPM_B_MIDDLE:                    mpCon->SelPaste(mTtyFd);                    return;                case GPM_B_RIGHT:                    if (mButtons == 3)                        mpCon->SelCopy(mX1, mY1, mX2, mY2, event.clicks);                    else                        mpCon->SelPaste(mTtyFd);                    return;            }    } /* switch above */#elif defined(__FreeBSD__)    struct mouse_info mi;    mi.operation = MOUSE_GETINFO;    if (ioctl(mConFd, CONS_MOUSECTL, &mi) < 0) {        //err(1, "CONS_MOUSECTL");        return;    }    //debug << mi.u.data.x << "," << mi.u.data.y << endl;    /*    if (mMiPrev.u.data.x == mi.u.data.x        && mMiPrev.u.data.y == mi.u.data.y        && mMiPrev.u.data.buttons == mi.u.data.buttons) {        return;    }    */       int x = (mi.u.data.x * mpCon->MaxCols()) / mpCon->Width();    int y = (mi.u.data.y * mpCon->MaxRows()) / mpCon->Height();    //debug<<"Mouse pointer ("<<x<<","<<y<<")";    /*    if (mX2 == x && mY2 == y        && mMiPrev.u.data.buttons == mi.u.data.buttons) {        return;    }    */    mX2 = x;    mY2 = y;    // based on gpm, gpm.c, function processMouse    MouseType evtype;    if (mMiPrev.u.data.buttons == mi.u.data.buttons) {        if (mi.u.data.buttons > 0) {            evtype = MOUSE_DRAG;            //debug << " drag";        } else {            evtype = MOUSE_MOVE;            //debug << " move";        }    } else {        if (mi.u.data.buttons > mMiPrev.u.data.buttons) {            evtype = MOUSE_DOWN;            //debug << " down";        } else {            evtype = MOUSE_UP;            //mi.u.data.buttons ^= mMiPrev.u.data.buttons;            //debug << " up";        }    }        int buttons = 0;    if (mi.u.data.buttons & MOUSE_BUTTON1DOWN) {        buttons = MOUSE_LEFT;        //debug << " left";    }    if (mi.u.data.buttons & MOUSE_BUTTON2DOWN) {        buttons = MOUSE_MIDDLE;        //debug << " middle";    }    if (mi.u.data.buttons & MOUSE_BUTTON3DOWN) {        buttons = MOUSE_RIGHT;        //debug << " right";    }    int clicks;    switch (evtype) {        case MOUSE_DOWN:            GET_TIME(mTV2);            // check first click            if (mTV1.tv_sec && DIF_TIME(mTV1, mTV2) < DEF_TIME) {                mClicks++;                mClicks %= 3;            } else {                mClicks = 0;            }            break;        case MOUSE_UP:            GET_TIME(mTV1);            break;        case MOUSE_DRAG:            break;        case MOUSE_MOVE:            mClicks = 0;        default:            break;    }    clicks = mClicks;    //debug << " clicks " << clicks << endl;       switch( evtype ) {        case MOUSE_MOVE:            mpCon->SelCopy(mX2, mY2, mX2, mY2,3); /* just highlight pointer */            break;        case MOUSE_DRAG:            if (buttons == MOUSE_LEFT) {                mpCon->SelCopy(mX1, mY1, mX2, mY2, clicks);                if (clicks >= DEF_PTRDRAG) /* pointer */                    mpCon->SelCopy(mX2, mY2, mX2, mY2, 3);            } /* if */            break;        case MOUSE_DOWN:            switch (buttons) {                case MOUSE_LEFT:                    mX1 = mX2;                    mY1 = mY2;                    mpCon->SelCopy(mX1, mY1, mX2, mY2, clicks);  /* start selection */                    break;                case MOUSE_MIDDLE:                    mpCon->SelPaste(mTtyFd);                    break;                case MOUSE_RIGHT:                    if (mButtons == 3)                        mpCon->SelCopy(mX1, mY1, mX2, mY2, clicks);                    else                        mpCon->SelPaste(mTtyFd);                    break;            }       default:           break;    } /* switch above */    memcpy(&mMiPrev, &mi, sizeof(mMiPrev));#endif    return;}

⌨️ 快捷键说明

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