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

📄 lib_mouse.c

📁 ncurses-5.4
💻 C
📖 第 1 页 / 共 3 页
字号:
	     * Take over SIGUSR2 for this purpose since SIGUSR1 is more	     * likely to be used by an application.  getch() will have to	     * handle the misleading EINTR's.	     */	    signal(SIGUSR2, SIG_IGN);	    the_mouse.operation = MOUSE_MODE;	    the_mouse.u.mode.mode = 0;	    the_mouse.u.mode.signal = SIGUSR2;	    if (ioctl(SP->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) {		signal(SIGUSR2, handle_sysmouse);		the_mouse.operation = MOUSE_SHOW;		ioctl(SP->_mouse_fd, CONS_MOUSECTL, &the_mouse);#if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO)	/* FreeBSD > 2.x */		{#ifndef FBIO_GETMODE		/* FreeBSD 3.x */#define FBIO_GETMODE    CONS_GET#define FBIO_MODEINFO   CONS_MODEINFO#endif /* FBIO_GETMODE */		    video_info_t the_video;		    if (ioctl(SP->_mouse_fd,			      FBIO_GETMODE,			      &the_video.vi_mode) != -1			&& ioctl(SP->_mouse_fd,				 FBIO_MODEINFO,				 &the_video) != -1) {			SP->_sysmouse_char_width = the_video.vi_cwidth;			SP->_sysmouse_char_height = the_video.vi_cheight;		    }		}#endif /* defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) */		if (SP->_sysmouse_char_width <= 0)		    SP->_sysmouse_char_width = 8;		if (SP->_sysmouse_char_height <= 0)		    SP->_sysmouse_char_height = 16;		SP->_mouse_type = M_SYSMOUSE;		return;	    }	}    }#endif /* USE_SYSMOUSE */    /* we know how to recognize mouse events under "xterm" */    if (key_mouse != 0) {	if (!strcmp(key_mouse, xterm_kmous)) {	    init_xterm_mouse();	    return;	}    } else if (strstr(cur_term->type.term_names, "xterm") != 0) {	(void) _nc_add_to_try(&(SP->_keytry), xterm_kmous, KEY_MOUSE);	init_xterm_mouse();	return;    }}static void_nc_mouse_init(void)/* initialize the mouse */{    int i;    if (!initialized) {	initialized = TRUE;	TR(MY_TRACE, ("_nc_mouse_init() called"));	for (i = 0; i < EV_MAX; i++)	    events[i].id = INVALID_EVENT;	initialize_mousetype();	T(("_nc_mouse_init() set mousetype to %d", SP->_mouse_type));    }}/* * Query to see if there is a pending mouse event.  This is called from * fifo_push() in lib_getch.c */static bool_nc_mouse_event(SCREEN * sp GCC_UNUSED){    bool result = FALSE;    switch (SP->_mouse_type) {    case M_XTERM:	/* xterm: never have to query, mouse events are in the keyboard stream */#if USE_EMX_MOUSE	{	    char kbuf[3];	    int i, res = read(M_FD(sp), &kbuf, 3);	/* Eat the prefix */	    if (res != 3)		printf("Got %d chars instead of 3 for prefix.\n", res);	    for (i = 0; i < res; i++) {		if (kbuf[i] != key_mouse[i])		    printf("Got char %d instead of %d for prefix.\n",			   (int) kbuf[i], (int) key_mouse[i]);	    }	    result = TRUE;	}#endif /* USE_EMX_MOUSE */	break;#if USE_GPM_SUPPORT    case M_GPM:	{	    /* query server for event, return TRUE if we find one */	    Gpm_Event ev;	    if (Gpm_GetEvent(&ev) == 1) {		/* there's only one mouse... */		eventp->id = NORMAL_EVENT;		eventp->bstate = 0;		switch (ev.type & 0x0f) {		case (GPM_DOWN):		    if (ev.buttons & GPM_B_LEFT)			eventp->bstate |= BUTTON1_PRESSED;		    if (ev.buttons & GPM_B_MIDDLE)			eventp->bstate |= BUTTON2_PRESSED;		    if (ev.buttons & GPM_B_RIGHT)			eventp->bstate |= BUTTON3_PRESSED;		    break;		case (GPM_UP):		    if (ev.buttons & GPM_B_LEFT)			eventp->bstate |= BUTTON1_RELEASED;		    if (ev.buttons & GPM_B_MIDDLE)			eventp->bstate |= BUTTON2_RELEASED;		    if (ev.buttons & GPM_B_RIGHT)			eventp->bstate |= BUTTON3_RELEASED;		    break;		default:		    break;		}		eventp->x = ev.x - 1;		eventp->y = ev.y - 1;		eventp->z = 0;		/* bump the next-free pointer into the circular list */		eventp = NEXT(eventp);		result = TRUE;	    }	}	break;#endif#if USE_SYSMOUSE    case M_SYSMOUSE:	if (SP->_sysmouse_head < SP->_sysmouse_tail) {	    *eventp = SP->_sysmouse_fifo[SP->_sysmouse_head];	    /*	     * Point the fifo-head to the next possible location.  If there	     * are none, reset the indices.  This may be interrupted by the	     * signal handler, doing essentially the same reset.	     */	    SP->_sysmouse_head += 1;	    if (SP->_sysmouse_head == SP->_sysmouse_tail) {		SP->_sysmouse_tail = 0;		SP->_sysmouse_head = 0;	    }	    /* bump the next-free pointer into the circular list */	    eventp = NEXT(eventp);	    result = TRUE;	}	break;#endif /* USE_SYSMOUSE */    case M_NONE:	break;    }    return result;		/* true if we found an event */}static bool_nc_mouse_inline(SCREEN * sp)/* mouse report received in the keyboard stream -- parse its info */{    bool result = FALSE;    TR(MY_TRACE, ("_nc_mouse_inline() called"));    if (SP->_mouse_type == M_XTERM) {	unsigned char kbuf[4];	mmask_t prev;	size_t grabbed;	int res;	/* This code requires that your xterm entry contain the kmous	 * capability and that it be set to the \E[M documented in the	 * Xterm Control Sequences reference.  This is how we	 * arrange for mouse events to be reported via a KEY_MOUSE	 * return value from wgetch().  After this value is received,	 * _nc_mouse_inline() gets called and is immediately	 * responsible for parsing the mouse status information	 * following the prefix.	 *	 * The following quotes from the ctrlseqs.ms document in the	 * X distribution, describing the X mouse tracking feature:	 *	 * Parameters for all mouse tracking escape sequences	 * generated by xterm encode numeric parameters in a single	 * character as value+040.  For example, !  is 1.	 *	 * On button press or release, xterm sends ESC [ M CbCxCy.	 * The low two bits of Cb encode button information: 0=MB1	 * pressed, 1=MB2 pressed, 2=MB3 pressed, 3=release.  The	 * upper bits encode what modifiers were down when the	 * button was pressed and are added together.  4=Shift,	 * 8=Meta, 16=Control.  Cx and Cy are the x and y coordinates	 * of the mouse event.  The upper left corner is (1,1).	 *	 * (End quote)  By the time we get here, we've eaten the	 * key prefix.  FYI, the loop below is necessary because	 * mouse click info isn't guaranteed to present as a	 * single clist item.  It always does under Linux but often	 * fails to under Solaris.	 */	for (grabbed = 0; grabbed < 3; grabbed += res) {	    /* For VIO mouse we add extra bit 64 to disambiguate button-up. */#if USE_EMX_MOUSE	    res = read(M_FD(sp) >= 0 ? M_FD(sp) : sp->_ifd, &kbuf, 3);#else	    res = read(sp->_ifd, kbuf + grabbed, 3 - grabbed);#endif	    if (res == -1)		break;	}	kbuf[3] = '\0';	TR(TRACE_IEVENT,	   ("_nc_mouse_inline sees the following xterm data: '%s'", kbuf));	/* there's only one mouse... */	eventp->id = NORMAL_EVENT;	/* processing code goes here */	eventp->bstate = 0;	prev = PREV(eventp)->bstate;#if USE_EMX_MOUSE#define PRESS_POSITION(n) \	eventp->bstate = MASK_PRESS(n); \	if (kbuf[0] & 0x40) \	    eventp->bstate = MASK_RELEASE(n)#else#define PRESS_POSITION(n) \	eventp->bstate = (prev & MASK_PRESS(n) \			? REPORT_MOUSE_POSITION \			: MASK_PRESS(n))#endif	switch (kbuf[0] & 0x3) {	case 0x0:	    PRESS_POSITION(1);	    break;	case 0x1:	    PRESS_POSITION(2);	    break;	case 0x2:	    PRESS_POSITION(3);	    break;	case 0x3:	    /*	     * Release events aren't reported for individual buttons, just for	     * the button set as a whole.  However, because there are normally	     * no mouse events under xterm that intervene between press and	     * release, we can infer the button actually released by looking at	     * the previous event.	     */	    if (prev & (BUTTON_PRESSED | BUTTON_RELEASED)) {		eventp->bstate = BUTTON_RELEASED;		if (!(prev & BUTTON1_PRESSED))		    eventp->bstate &= ~BUTTON1_RELEASED;		if (!(prev & BUTTON2_PRESSED))		    eventp->bstate &= ~BUTTON2_RELEASED;		if (!(prev & BUTTON3_PRESSED))		    eventp->bstate &= ~BUTTON3_RELEASED;	    } else {		/*		 * XFree86 xterm will return a stream of release-events to		 * let the application know where the mouse is going, if the		 * private mode 1002 or 1003 is enabled.		 */		eventp->bstate = REPORT_MOUSE_POSITION;	    }	    break;	}	result = (eventp->bstate & REPORT_MOUSE_POSITION) ? TRUE : FALSE;	if (kbuf[0] & 4) {	    eventp->bstate |= BUTTON_SHIFT;	}	if (kbuf[0] & 8) {	    eventp->bstate |= BUTTON_ALT;	}	if (kbuf[0] & 16) {	    eventp->bstate |= BUTTON_CTRL;	}	eventp->x = (kbuf[1] - ' ') - 1;	eventp->y = (kbuf[2] - ' ') - 1;	TR(MY_TRACE,	   ("_nc_mouse_inline: primitive mouse-event %s has slot %ld",	    _tracemouse(eventp),	    (long) (eventp - events)));	/* bump the next-free pointer into the circular list */	eventp = NEXT(eventp);#if 0				/* this return would be needed for QNX's mods to lib_getch.c */	return (TRUE);#endif    }    return (result);}static voidmouse_activate(bool on){    if (!on && !initialized)	return;    _nc_mouse_init();    if (on) {	switch (SP->_mouse_type) {	case M_XTERM:#if NCURSES_EXT_FUNCS	    keyok(KEY_MOUSE, on);#endif	    TPUTS_TRACE("xterm mouse initialization");#if USE_EMX_MOUSE	    server_state(1);#else	    enable_xterm_mouse(1);#endif	    break;#if USE_GPM_SUPPORT	case M_GPM:	    SP->_mouse_fd = gpm_fd;	    break;#endif#if USE_SYSMOUSE	case M_SYSMOUSE:	    signal(SIGUSR2, handle_sysmouse);	    break;#endif	case M_NONE:	    return;	}	/* 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");#if USE_EMX_MOUSE	    server_state(0);#else	    enable_xterm_mouse(0);#endif	    break;#if USE_GPM_SUPPORT	case M_GPM:	    break;#endif#if USE_SYSMOUSE	case M_SYSMOUSE:	    signal(SIGUSR2, SIG_IGN);	    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;    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.

⌨️ 快捷键说明

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