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

📄 lib_mouse.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	/* Make runtime binding to cut down on object size of applications that	 * do not use the mouse (e.g., 'clear').	 */	SP->_mouse_event = _nc_mouse_event;	SP->_mouse_inline = _nc_mouse_inline;	SP->_mouse_parse = _nc_mouse_parse;	SP->_mouse_resume = _nc_mouse_resume;	SP->_mouse_wrap = _nc_mouse_wrap;    } else {	switch (SP->_mouse_type) {	case M_XTERM:	    TPUTS_TRACE("xterm mouse deinitialization");	    enable_xterm_mouse(0);	    break;#if USE_GPM_SUPPORT	case M_GPM:	    enable_gpm_mouse(0);	    break;#endif#if USE_SYSMOUSE	case M_SYSMOUSE:	    signal(SIGUSR2, SIG_IGN);	    SP->_mouse_active = FALSE;	    break;#endif	case M_NONE:	    return;	}    }    _nc_flush();}/************************************************************************** * * Device-independent code * **************************************************************************/static bool_nc_mouse_parse(int runcount)/* parse a run of atomic mouse events into a gesture */{    MEVENT *ep, *runp, *next, *prev = PREV(eventp);    int n;    int b;    bool merge;    TR(MY_TRACE, ("_nc_mouse_parse(%d) called", runcount));    /*     * When we enter this routine, the event list next-free pointer     * points just past a run of mouse events that we know were separated     * in time by less than the critical click interval. The job of this     * routine is to collapse this run into a single higher-level event     * or gesture.     *     * We accomplish this in two passes.  The first pass merges press/release     * pairs into click events.  The second merges runs of click events into     * double or triple-click events.     *     * It's possible that the run may not resolve to a single event (for     * example, if the user quadruple-clicks).  If so, leading events     * in the run are ignored.     *     * Note that this routine is independent of the format of the specific     * format of the pointing-device's reports.  We can use it to parse     * gestures on anything that reports press/release events on a per-     * button basis, as long as the device-dependent mouse code puts stuff     * on the queue in MEVENT format.     */    if (runcount == 1) {	TR(MY_TRACE,	   ("_nc_mouse_parse: returning simple mouse event %s at slot %ld",	    _tracemouse(prev),	    (long) (prev - events)));	return (prev->id >= NORMAL_EVENT)	    ? ((prev->bstate & eventmask) ? TRUE : FALSE)	    : FALSE;    }    /* find the start of the run */    runp = eventp;    for (n = runcount; n > 0; n--) {	runp = PREV(runp);    }#ifdef TRACE    if (_nc_tracing & TRACE_IEVENT) {	_trace_slot("before mouse press/release merge:");	_tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",		(long) (runp - events),		(long) ((eventp - events) + (EV_MAX - 1)) % EV_MAX,		runcount);    }#endif /* TRACE */    /* first pass; merge press/release pairs */    do {	merge = FALSE;	for (ep = runp; (next = NEXT(ep)) != eventp; ep = next) {#define MASK_CHANGED(x) (!(ep->bstate & MASK_PRESS(x)) \		      == !(next->bstate & MASK_RELEASE(x)))	    if (ep->x == next->x && ep->y == next->y		&& (ep->bstate & BUTTON_PRESSED)		&& MASK_CHANGED(1)		&& MASK_CHANGED(2)		&& MASK_CHANGED(3)		&& MASK_CHANGED(4)#if NCURSES_MOUSE_VERSION == 2		&& MASK_CHANGED(5)#endif		) {		for (b = 1; b <= MAX_BUTTONS; ++b) {		    if ((eventmask & MASK_CLICK(b))			&& (ep->bstate & MASK_PRESS(b))) {			ep->bstate &= ~MASK_PRESS(b);			ep->bstate |= MASK_CLICK(b);			merge = TRUE;		    }		}		if (merge)		    next->id = INVALID_EVENT;	    }	}    } while	(merge);#ifdef TRACE    if (_nc_tracing & TRACE_IEVENT) {	_trace_slot("before mouse click merge:");	_tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",		(long) (runp - events),		(long) ((eventp - events) + (EV_MAX - 1)) % EV_MAX,		runcount);    }#endif /* TRACE */    /*     * Second pass; merge click runs.  At this point, click events are     * each followed by one invalid event. We merge click events     * forward in the queue.     *     * NOTE: There is a problem with this design!  If the application     * allows enough click events to pile up in the circular queue so     * they wrap around, it will cheerfully merge the newest forward     * into the oldest, creating a bogus doubleclick and confusing     * the queue-traversal logic rather badly.  Generally this won't     * happen, because calling getmouse() marks old events invalid and     * ineligible for merges.  The true solution to this problem would     * be to timestamp each MEVENT and perform the obvious sanity check,     * but the timer element would have to have sub-second resolution,     * which would get us into portability trouble.     */    do {	MEVENT *follower;	merge = FALSE;	for (ep = runp; (next = NEXT(ep)) != eventp; ep = next)	    if (ep->id != INVALID_EVENT) {		if (next->id != INVALID_EVENT)		    continue;		follower = NEXT(next);		if (follower->id == INVALID_EVENT)		    continue;		/* merge click events forward */		if ((ep->bstate & BUTTON_CLICKED)		    && (follower->bstate & BUTTON_CLICKED)) {		    for (b = 1; b <= MAX_BUTTONS; ++b) {			if ((eventmask & MASK_DOUBLE_CLICK(b))			    && (follower->bstate & MASK_CLICK(b))) {			    follower->bstate &= ~MASK_CLICK(b);			    follower->bstate |= MASK_DOUBLE_CLICK(b);			    merge = TRUE;			}		    }		    if (merge)			ep->id = INVALID_EVENT;		}		/* merge double-click events forward */		if ((ep->bstate & BUTTON_DOUBLE_CLICKED)		    && (follower->bstate & BUTTON_CLICKED)) {		    for (b = 1; b <= MAX_BUTTONS; ++b) {			if ((eventmask & MASK_TRIPLE_CLICK(b))			    && (follower->bstate & MASK_CLICK(b))) {			    follower->bstate &= ~MASK_CLICK(b);			    follower->bstate |= MASK_TRIPLE_CLICK(b);			    merge = TRUE;			}		    }		    if (merge)			ep->id = INVALID_EVENT;		}	    }    } while	(merge);#ifdef TRACE    if (_nc_tracing & TRACE_IEVENT) {	_trace_slot("before mouse event queue compaction:");	_tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",		(long) (runp - events),		(long) ((eventp - events) + (EV_MAX - 1)) % EV_MAX,		runcount);    }#endif /* TRACE */    /*     * Now try to throw away trailing events flagged invalid, or that     * don't match the current event mask.     */    for (; runcount; prev = PREV(eventp), runcount--)	if (prev->id == INVALID_EVENT || !(prev->bstate & eventmask)) {	    eventp = prev;	}#ifdef TRACE    if (_nc_tracing & TRACE_IEVENT) {	_trace_slot("after mouse event queue compaction:");	_tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",		(long) (runp - events),		(long) ((eventp - events) + (EV_MAX - 1)) % EV_MAX,		runcount);    }    for (ep = runp; ep != eventp; ep = NEXT(ep))	if (ep->id != INVALID_EVENT)	    TR(MY_TRACE,	       ("_nc_mouse_parse: returning composite mouse event %s at slot %ld",		_tracemouse(ep),		(long) (ep - events)));#endif /* TRACE */    /* after all this, do we have a valid event? */    return (PREV(eventp)->id != INVALID_EVENT);}static void_nc_mouse_wrap(SCREEN *sp GCC_UNUSED)/* release mouse -- called by endwin() before shellout/exit */{    TR(MY_TRACE, ("_nc_mouse_wrap() called"));    switch (SP->_mouse_type) {    case M_XTERM:	if (eventmask)	    mouse_activate(FALSE);	break;#if USE_GPM_SUPPORT	/* GPM: pass all mouse events to next client */    case M_GPM:	if (eventmask)	    mouse_activate(FALSE);	break;#endif#if USE_SYSMOUSE    case M_SYSMOUSE:	mouse_activate(FALSE);	break;#endif    case M_NONE:	break;    }}static void_nc_mouse_resume(SCREEN *sp GCC_UNUSED)/* re-connect to mouse -- called by doupdate() after shellout */{    TR(MY_TRACE, ("_nc_mouse_resume() called"));    switch (SP->_mouse_type) {    case M_XTERM:	/* xterm: re-enable reporting */	if (eventmask)	    mouse_activate(TRUE);	break;#if USE_GPM_SUPPORT    case M_GPM:	/* GPM: reclaim our event set */	if (eventmask)	    mouse_activate(TRUE);	break;#endif#if USE_SYSMOUSE    case M_SYSMOUSE:	mouse_activate(TRUE);	break;#endif    case M_NONE:	break;    }}/************************************************************************** * * Mouse interface entry points for the API * **************************************************************************/NCURSES_EXPORT(int)getmouse(MEVENT * aevent)/* grab a copy of the current mouse event */{    T((T_CALLED("getmouse(%p)"), aevent));    if (aevent && (SP->_mouse_type != M_NONE)) {	/* compute the current-event pointer */	MEVENT *prev = PREV(eventp);	/* copy the event we find there */	*aevent = *prev;	TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %ld",			  _tracemouse(prev),			  (long) (prev - events)));	prev->id = INVALID_EVENT;	/* so the queue slot becomes free */	returnCode(OK);    }    returnCode(ERR);}NCURSES_EXPORT(int)ungetmouse(MEVENT * aevent)/* enqueue a synthesized mouse event to be seen by the next wgetch() */{    T((T_CALLED("ungetmouse(%p)"), aevent));    /* stick the given event in the next-free slot */    *eventp = *aevent;    /* bump the next-free pointer into the circular list */    eventp = NEXT(eventp);    /* push back the notification event on the keyboard queue */    returnCode(ungetch(KEY_MOUSE));}NCURSES_EXPORT(mmask_t)mousemask(mmask_t newmask, mmask_t * oldmask)/* set the mouse event mask */{    mmask_t result = 0;    T((T_CALLED("mousemask(%#lx,%p)"), (unsigned long) newmask, oldmask));    if (oldmask)	*oldmask = eventmask;    if (!newmask && !initialized)	returnBits(0);    _nc_mouse_init();    if (SP != 0 && SP->_mouse_type != M_NONE) {	eventmask = newmask &	    (REPORT_MOUSE_POSITION | BUTTON_ALT | BUTTON_CTRL | BUTTON_SHIFT	     | BUTTON_PRESSED	     | BUTTON_RELEASED	     | BUTTON_CLICKED	     | BUTTON_DOUBLE_CLICKED	     | BUTTON_TRIPLE_CLICKED);	mouse_activate(eventmask != 0);	result = eventmask;    }    returnBits(result);}NCURSES_EXPORT(bool)wenclose(const WINDOW *win, int y, int x)/* check to see if given window encloses given screen location */{    bool result = FALSE;    T((T_CALLED("wenclose(%p,%d,%d)"), win, y, x));    if (win != 0) {	y -= win->_yoffset;	result = ((win->_begy <= y &&		   win->_begx <= x &&		   (win->_begx + win->_maxx) >= x &&		   (win->_begy + win->_maxy) >= y) ? TRUE : FALSE);    }    returnBool(result);}NCURSES_EXPORT(int)mouseinterval(int maxclick)/* set the maximum mouse interval within which to recognize a click */{    int oldval;    T((T_CALLED("mouseinterval(%d)"), maxclick));    if (SP != 0) {	oldval = SP->_maxclick;	if (maxclick >= 0)	    SP->_maxclick = maxclick;    } else {	oldval = DEFAULT_MAXCLICK;    }    returnCode(oldval);}/* This may be used by other routines to ask for the existence of mouse   support */NCURSES_EXPORT(int)_nc_has_mouse(void){    return (SP->_mouse_type == M_NONE ? 0 : 1);}NCURSES_EXPORT(bool)wmouse_trafo(const WINDOW *win, int *pY, int *pX, bool to_screen){    bool result = FALSE;    T((T_CALLED("wmouse_trafo(%p,%p,%p,%d)"), win, pY, pX, to_screen));    if (win && pY && pX) {	int y = *pY;	int x = *pX;	if (to_screen) {	    y += win->_begy + win->_yoffset;	    x += win->_begx;	    if (wenclose(win, y, x))		result = TRUE;	} else {	    if (wenclose(win, y, x)) {		y -= (win->_begy + win->_yoffset);		x -= win->_begx;		result = TRUE;	    }	}	if (result) {	    *pX = x;	    *pY = y;	}    }    returnBool(result);}

⌨️ 快捷键说明

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