X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_mouse.c;h=e92be5b92fe0f8a716bf8876070aa6b4f1845284;hp=7bb20de55b799f37be6f68593d56c5060320e57c;hb=1c2ec25b8186b7973aeb06ec4da6b63656e12f7d;hpb=55ccd2b959766810cf7db8d1c4462f338ce0afc8 diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index 7bb20de5..e92be5b9 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -79,18 +79,18 @@ #include -MODULE_ID("$Id: lib_mouse.c,v 1.77 2005/09/10 22:58:57 tom Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.98 2008/09/20 21:26:19 tom Exp $") #include #include #if USE_GPM_SUPPORT -#ifndef LINT /* don't need this for llib-lncurses */ -#undef buttons /* term.h defines this, and gpm uses it! */ -#include #include /* defines KG_* macros */ + +#ifdef HAVE_LIBDL /* use dynamic loader to avoid linkage dependency */ #include + #ifdef RTLD_NOW #define my_RTLD RTLD_NOW #else @@ -99,8 +99,9 @@ MODULE_ID("$Id: lib_mouse.c,v 1.77 2005/09/10 22:58:57 tom Exp $") #else make an error #endif -#endif -#endif +#endif /* RTLD_NOW */ +#endif /* HAVE_LIBDL */ + #endif /* USE_GPM_SUPPORT */ #if USE_SYSMOUSE @@ -144,62 +145,52 @@ make an error #define NORMAL_EVENT 0 #if USE_GPM_SUPPORT -#ifndef LINT #ifndef LIBGPM_SONAME #define LIBGPM_SONAME "libgpm.so" #endif -#define GET_DLSYM(name) (my_##name = (TYPE_##name) dlsym(obj, #name)) - -static Gpm_Connect gpm_connect; - -typedef int *TYPE_gpm_fd; -typedef int (*TYPE_Gpm_Open) (Gpm_Connect *, int); -typedef int (*TYPE_Gpm_Close) (void); -typedef int (*TYPE_Gpm_GetEvent) (Gpm_Event *); - -static TYPE_gpm_fd my_gpm_fd; -static TYPE_Gpm_Open my_Gpm_Open; -static TYPE_Gpm_Close my_Gpm_Close; -static TYPE_Gpm_GetEvent my_Gpm_GetEvent; +#define GET_DLSYM(name) (my_##name = (TYPE_##name) dlsym(SP->_dlopen_gpm, #name)) -#endif /* LINT */ -#endif /* USE_GPM_SUPPORT */ - -static mmask_t eventmask; /* current event mask */ +#endif /* USE_GPM_SUPPORT */ -static bool _nc_mouse_parse(int); +static bool _nc_mouse_parse(SCREEN *, int); static void _nc_mouse_resume(SCREEN *); static void _nc_mouse_wrap(SCREEN *); /* maintain a circular list of mouse events */ -/* The definition of the circular list size (EV_MAX), is in curses.priv.h, so - * wgetch() may refer to the size and call _nc_mouse_parse() before circular - * list overflow. - */ -static MEVENT events[EV_MAX]; /* hold the last mouse event seen */ -static MEVENT *eventp = events; /* next free slot in event queue */ +#define FirstEV(sp) ((sp)->_mouse_events) +#define LastEV(sp) ((sp)->_mouse_events + EV_MAX - 1) #undef NEXT -#define NEXT(ep) ((ep == events + EV_MAX - 1) ? events : ep + 1) +#define NEXT(ep) ((ep >= LastEV(sp)) \ + ? FirstEV(sp) \ + : ep + 1) #undef PREV -#define PREV(ep) ((ep == events) ? events + EV_MAX - 1 : ep - 1) +#define PREV(ep) ((ep <= FirstEV(sp)) \ + ? LastEV(sp) \ + : ep - 1) + +#define IndexEV(sp, ep) (ep - FirstEV(sp)) + +#define RunParams(sp, eventp, runp) \ + (long) IndexEV(sp, runp), \ + (long) (IndexEV(sp, eventp) + (EV_MAX - 1)) % EV_MAX #ifdef TRACE static void -_trace_slot(const char *tag) +_trace_slot(SCREEN *sp, const char *tag) { MEVENT *ep; _tracef(tag); - for (ep = events; ep < events + EV_MAX; ep++) + for (ep = FirstEV(sp); ep <= LastEV(sp); ep++) _tracef("mouse event queue slot %ld = %s", - (long) (ep - events), - _tracemouse(ep)); + (long) IndexEV(sp, ep), + _nc_tracemouse(sp, ep)); } #endif @@ -208,16 +199,10 @@ _trace_slot(const char *tag) # define TOP_ROW 0 # define LEFT_COL 0 -static int mouse_wfd; -static int mouse_thread; -static int mouse_activated; -static char mouse_buttons[] = -{0, 1, 3, 2}; - # define M_FD(sp) sp->_mouse_fd static void -write_event(int down, int button, int x, int y) +write_event(SCREEN *sp, int down, int button, int x, int y) { char buf[6]; unsigned long ignore; @@ -226,12 +211,13 @@ write_event(int down, int button, int x, int y) buf[3] = ' ' + (button - 1) + (down ? 0 : 0x40); buf[4] = ' ' + x - LEFT_COL + 1; buf[5] = ' ' + y - TOP_ROW + 1; - DosWrite(mouse_wfd, buf, 6, &ignore); + DosWrite(sp->_emxmouse_wfd, buf, 6, &ignore); } static void -mouse_server(unsigned long ignored GCC_UNUSED) +mouse_server(unsigned long param) { + SCREEN *sp = (SCREEN *) param; unsigned short fWait = MOU_WAIT; /* NOPTRRECT mourt = { 0,0,24,79 }; */ MOUEVENTINFO mouev; @@ -258,7 +244,7 @@ mouse_server(unsigned long ignored GCC_UNUSED) sprintf(err, "Error reading mouse queue, rc=%lu.\r\n", rc); break; } - if (!mouse_activated) + if (!sp->_emxmouse_activated) goto finish; /* @@ -270,13 +256,13 @@ mouse_server(unsigned long ignored GCC_UNUSED) */ if ((mouev.fs ^ oldstate) & MOUSE_BN1_DOWN) write_event(mouev.fs & MOUSE_BN1_DOWN, - mouse_buttons[1], mouev.col, mouev.row); + sp->_emxmouse_buttons[1], mouev.col, mouev.row); if ((mouev.fs ^ oldstate) & MOUSE_BN2_DOWN) write_event(mouev.fs & MOUSE_BN2_DOWN, - mouse_buttons[3], mouev.col, mouev.row); + sp->_emxmouse_buttons[3], mouev.col, mouev.row); if ((mouev.fs ^ oldstate) & MOUSE_BN3_DOWN) write_event(mouev.fs & MOUSE_BN3_DOWN, - mouse_buttons[2], mouev.col, mouev.row); + sp->_emxmouse_buttons[2], mouev.col, mouev.row); finish: oldstate = mouev.fs; @@ -295,83 +281,87 @@ mouse_server(unsigned long ignored GCC_UNUSED) #if USE_SYSMOUSE static void -handle_sysmouse(int sig GCC_UNUSED) +sysmouse_server(SCREEN *sp) { struct mouse_info the_mouse; MEVENT *work; the_mouse.operation = MOUSE_GETINFO; - if (SP != 0 - && SP->_mouse_fd >= 0 - && SP->_sysmouse_tail < FIFO_SIZE - && ioctl(SP->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) { - - if (SP->_sysmouse_head > SP->_sysmouse_tail) { - SP->_sysmouse_tail = 0; - SP->_sysmouse_head = 0; + if (sp != 0 + && sp->_mouse_fd >= 0 + && sp->_sysmouse_tail < FIFO_SIZE + && ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) { + + if (sp->_sysmouse_head > sp->_sysmouse_tail) { + sp->_sysmouse_tail = 0; + sp->_sysmouse_head = 0; } - work = &(SP->_sysmouse_fifo[SP->_sysmouse_tail]); + work = &(sp->_sysmouse_fifo[sp->_sysmouse_tail]); memset(work, 0, sizeof(*work)); work->id = NORMAL_EVENT; /* there's only one mouse... */ - SP->_sysmouse_old_buttons = SP->_sysmouse_new_buttons; - SP->_sysmouse_new_buttons = the_mouse.u.data.buttons & 0x7; + sp->_sysmouse_old_buttons = sp->_sysmouse_new_buttons; + sp->_sysmouse_new_buttons = the_mouse.u.data.buttons & 0x7; - if (SP->_sysmouse_new_buttons) { - if (SP->_sysmouse_new_buttons & 1) + if (sp->_sysmouse_new_buttons) { + if (sp->_sysmouse_new_buttons & 1) work->bstate |= BUTTON1_PRESSED; - if (SP->_sysmouse_new_buttons & 2) + if (sp->_sysmouse_new_buttons & 2) work->bstate |= BUTTON2_PRESSED; - if (SP->_sysmouse_new_buttons & 4) + if (sp->_sysmouse_new_buttons & 4) work->bstate |= BUTTON3_PRESSED; } else { - if (SP->_sysmouse_old_buttons & 1) + if (sp->_sysmouse_old_buttons & 1) work->bstate |= BUTTON1_RELEASED; - if (SP->_sysmouse_old_buttons & 2) + if (sp->_sysmouse_old_buttons & 2) work->bstate |= BUTTON2_RELEASED; - if (SP->_sysmouse_old_buttons & 4) + if (sp->_sysmouse_old_buttons & 4) work->bstate |= BUTTON3_RELEASED; } /* for cosmetic bug in syscons.c on FreeBSD 3.[34] */ the_mouse.operation = MOUSE_HIDE; - ioctl(SP->_mouse_fd, CONS_MOUSECTL, &the_mouse); + ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse); the_mouse.operation = MOUSE_SHOW; - ioctl(SP->_mouse_fd, CONS_MOUSECTL, &the_mouse); + ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse); /* * We're only interested if the button is pressed or released. * FIXME: implement continuous event-tracking. */ - if (SP->_sysmouse_new_buttons != SP->_sysmouse_old_buttons) { - SP->_sysmouse_tail += 1; + if (sp->_sysmouse_new_buttons != sp->_sysmouse_old_buttons) { + sp->_sysmouse_tail += 1; } - work->x = the_mouse.u.data.x / SP->_sysmouse_char_width; - work->y = the_mouse.u.data.y / SP->_sysmouse_char_height; + work->x = the_mouse.u.data.x / sp->_sysmouse_char_width; + work->y = the_mouse.u.data.y / sp->_sysmouse_char_height; } } -#endif /* USE_SYSMOUSE */ -static int initialized; +static void +handle_sysmouse(int sig GCC_UNUSED) +{ + sysmouse_server(SP); +} +#endif /* USE_SYSMOUSE */ static void -init_xterm_mouse(void) +init_xterm_mouse(SCREEN *sp) { - SP->_mouse_type = M_XTERM; - SP->_mouse_xtermcap = tigetstr("XM"); - if (!VALID_STRING(SP->_mouse_xtermcap)) - SP->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; + sp->_mouse_type = M_XTERM; + sp->_mouse_xtermcap = tigetstr("XM"); + if (!VALID_STRING(sp->_mouse_xtermcap)) + sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; } static void -enable_xterm_mouse(int enable) +enable_xterm_mouse(SCREEN *sp, int enable) { #if USE_EMX_MOUSE - mouse_activated = enable; + sp->_emxmouse_activated = enable; #else - putp(tparm(SP->_mouse_xtermcap, enable)); + putp(TPARM_1(sp->_mouse_xtermcap, enable)); #endif - SP->_mouse_active = enable; + sp->_mouse_active = enable; } #if USE_GPM_SUPPORT @@ -392,69 +382,79 @@ allow_gpm_mouse(void) } static bool -enable_gpm_mouse(int enable) +enable_gpm_mouse(SCREEN *sp, int enable) { bool result; T((T_CALLED("enable_gpm_mouse(%d)"), enable)); - if (enable && !SP->_mouse_active) { + if (enable && !sp->_mouse_active) { /* GPM: initialize connection to gpm server */ - gpm_connect.eventMask = GPM_DOWN | GPM_UP; - gpm_connect.defaultMask = ~(gpm_connect.eventMask | GPM_HARD); - gpm_connect.minMod = 0; - gpm_connect.maxMod = (unsigned short) (~((1 << KG_SHIFT) | - (1 << KG_SHIFTL) | - (1 << KG_SHIFTR))); + sp->_mouse_gpm_connect.eventMask = GPM_DOWN | GPM_UP; + sp->_mouse_gpm_connect.defaultMask = + (unsigned short) (~(sp->_mouse_gpm_connect.eventMask | GPM_HARD)); + sp->_mouse_gpm_connect.minMod = 0; + sp->_mouse_gpm_connect.maxMod = + (unsigned short) (~((1 << KG_SHIFT) | + (1 << KG_SHIFTL) | + (1 << KG_SHIFTR))); /* * Note: GPM hardcodes \E[?1001s and \E[?1000h during its open. * The former is recognized by wscons (SunOS), and the latter by * xterm. Those will not show up in ncurses' traces. */ - result = (my_Gpm_Open(&gpm_connect, 0) >= 0); - SP->_mouse_active = result; + result = (my_Gpm_Open(&sp->_mouse_gpm_connect, 0) >= 0); + sp->_mouse_active = result; T(("GPM open %s", result ? "succeeded" : "failed")); } else { - if (!enable && SP->_mouse_active) { + if (!enable && sp->_mouse_active) { /* GPM: close connection to gpm server */ my_Gpm_Close(); - SP->_mouse_active = FALSE; + sp->_mouse_active = FALSE; T(("GPM closed")); } result = FALSE; } +#ifdef HAVE_LIBDL + if (!result && (SP->_dlopen_gpm != 0)) { + T(("unload GPM library")); + SP->_mouse_gpm_found = FALSE; + SP->_mouse_gpm_loaded = FALSE; + dlclose(SP->_dlopen_gpm); + SP->_dlopen_gpm = 0; + } +#endif returnBool(result); } #endif /* USE_GPM_SUPPORT */ +#define xterm_kmous "\033[M" + static void -initialize_mousetype(void) +initialize_mousetype(SCREEN *sp) { - static const char *xterm_kmous = "\033[M"; - T((T_CALLED("initialize_mousetype()"))); /* Try gpm first, because gpm may be configured to run in xterm */ #if USE_GPM_SUPPORT if (allow_gpm_mouse()) { - static bool first = TRUE; - static bool found = FALSE; - - if (first) { - void *obj; - first = FALSE; - - if ((obj = dlopen(LIBGPM_SONAME, my_RTLD)) != 0) { + if (!sp->_mouse_gpm_loaded) { +#ifdef HAVE_LIBDL + if ((SP->_dlopen_gpm = dlopen(LIBGPM_SONAME, my_RTLD)) != 0) { if (GET_DLSYM(gpm_fd) == 0 || GET_DLSYM(Gpm_Open) == 0 || GET_DLSYM(Gpm_Close) == 0 || GET_DLSYM(Gpm_GetEvent) == 0) { T(("GPM initialization failed: %s", dlerror())); - dlclose(obj); + dlclose(SP->_dlopen_gpm); } else { - found = TRUE; + sp->_mouse_gpm_found = TRUE; } } +#else /* !HAVE_LIBDL */ + sp->_mouse_gpm_found = TRUE; +#endif + sp->_mouse_gpm_loaded = TRUE; } /* @@ -462,10 +462,10 @@ initialize_mousetype(void) * maintain our notion of whether the mouse connection is active * without testing the file-descriptor. */ - if (found && enable_gpm_mouse(TRUE)) { - SP->_mouse_type = M_GPM; - SP->_mouse_fd = *my_gpm_fd; - T(("GPM mouse_fd %d", SP->_mouse_fd)); + if (sp->_mouse_gpm_found && enable_gpm_mouse(sp, TRUE)) { + sp->_mouse_type = M_GPM; + sp->_mouse_fd = *(my_gpm_fd); + T(("GPM mouse_fd %d", sp->_mouse_fd)); returnVoid; } } @@ -473,7 +473,7 @@ initialize_mousetype(void) /* OS/2 VIO */ #if USE_EMX_MOUSE - if (!mouse_thread + if (!sp->_emxmouse_thread && strstr(cur_term->type.term_names, "xterm") == 0 && key_mouse) { int handles[2]; @@ -484,28 +484,32 @@ initialize_mousetype(void) } else { int rc; - if (!mouse_buttons[0]) { + if (!sp->_emxmouse_buttons[0]) { char *s = getenv("MOUSE_BUTTONS_123"); - mouse_buttons[0] = 1; + sp->_emxmouse_buttons[0] = 1; if (s && strlen(s) >= 3) { - mouse_buttons[1] = s[0] - '0'; - mouse_buttons[2] = s[1] - '0'; - mouse_buttons[3] = s[2] - '0'; + sp->_emxmouse_buttons[1] = s[0] - '0'; + sp->_emxmouse_buttons[2] = s[1] - '0'; + sp->_emxmouse_buttons[3] = s[2] - '0'; + } else { + sp->_emxmouse_buttons[1] = 1; + sp->_emxmouse_buttons[2] = 3; + sp->_emxmouse_buttons[3] = 2; } } - mouse_wfd = handles[1]; - M_FD(SP) = handles[0]; + sp->_emxmouse_wfd = handles[1]; + M_FD(sp) = handles[0]; /* Needed? */ setmode(handles[0], O_BINARY); setmode(handles[1], O_BINARY); /* Do not use CRT functions, we may single-threaded. */ - rc = DosCreateThread((unsigned long *) &mouse_thread, - mouse_server, 0, 0, 8192); + rc = DosCreateThread((unsigned long *) &sp->_emxmouse_thread, + mouse_server, sp, 0, 8192); if (rc) { printf("mouse thread error %d=%#x", rc, rc); } else { - SP->_mouse_type = M_XTERM; + sp->_mouse_type = M_XTERM; } returnVoid; } @@ -517,14 +521,14 @@ initialize_mousetype(void) struct mouse_info the_mouse; char *the_device = 0; - if (isatty(SP->_ifd)) - the_device = ttyname(SP->_ifd); + if (isatty(sp->_ifd)) + the_device = ttyname(sp->_ifd); if (the_device == 0) the_device = "/dev/tty"; - SP->_mouse_fd = open(the_device, O_RDWR); + sp->_mouse_fd = open(the_device, O_RDWR); - if (SP->_mouse_fd >= 0) { + if (sp->_mouse_fd >= 0) { /* * sysmouse does not have a usable user interface for obtaining * mouse events. The logical way to proceed (reading data on a @@ -541,10 +545,10 @@ initialize_mousetype(void) 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) { + 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); + ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse); #if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) /* FreeBSD > 2.x */ { @@ -554,23 +558,23 @@ initialize_mousetype(void) #endif /* FBIO_GETMODE */ video_info_t the_video; - if (ioctl(SP->_mouse_fd, + if (ioctl(sp->_mouse_fd, FBIO_GETMODE, &the_video.vi_mode) != -1 - && ioctl(SP->_mouse_fd, + && 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; + 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; + 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; returnVoid; } } @@ -579,35 +583,41 @@ initialize_mousetype(void) /* we know how to recognize mouse events under "xterm" */ if (key_mouse != 0) { - if (!strcmp(key_mouse, xterm_kmous)) { - init_xterm_mouse(); + if (!strcmp(key_mouse, xterm_kmous) + || strstr(cur_term->type.term_names, "xterm") != 0) { + init_xterm_mouse(sp); } } else if (strstr(cur_term->type.term_names, "xterm") != 0) { - (void) _nc_add_to_try(&(SP->_keytry), xterm_kmous, KEY_MOUSE); - init_xterm_mouse(); + if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) + init_xterm_mouse(sp); } returnVoid; } static bool -_nc_mouse_init(void) +_nc_mouse_init(SCREEN *sp) /* initialize the mouse */ { + bool result = FALSE; int i; - if (!initialized && (SP != 0)) { - initialized = TRUE; + if (sp != 0) { + if (!sp->_mouse_initialized) { + sp->_mouse_initialized = TRUE; - TR(MY_TRACE, ("_nc_mouse_init() called")); + TR(MY_TRACE, ("_nc_mouse_init() called")); - for (i = 0; i < EV_MAX; i++) - events[i].id = INVALID_EVENT; + sp->_mouse_eventp = FirstEV(sp); + for (i = 0; i < EV_MAX; i++) + sp->_mouse_events[i].id = INVALID_EVENT; - initialize_mousetype(); + initialize_mousetype(sp); - T(("_nc_mouse_init() set mousetype to %d", SP->_mouse_type)); + T(("_nc_mouse_init() set mousetype to %d", sp->_mouse_type)); + } + result = sp->_mouse_initialized; } - return initialized; + return result; } /* @@ -617,9 +627,12 @@ _nc_mouse_init(void) static bool _nc_mouse_event(SCREEN *sp GCC_UNUSED) { + MEVENT *eventp = sp->_mouse_eventp; bool result = FALSE; - switch (SP->_mouse_type) { + (void) eventp; + + switch (sp->_mouse_type) { case M_XTERM: /* xterm: never have to query, mouse events are in the keyboard stream */ #if USE_EMX_MOUSE @@ -676,7 +689,7 @@ _nc_mouse_event(SCREEN *sp GCC_UNUSED) eventp->z = 0; /* bump the next-free pointer into the circular list */ - eventp = NEXT(eventp); + sp->_mouse_eventp = eventp = NEXT(eventp); result = TRUE; } } @@ -685,22 +698,22 @@ _nc_mouse_event(SCREEN *sp GCC_UNUSED) #if USE_SYSMOUSE case M_SYSMOUSE: - if (SP->_sysmouse_head < SP->_sysmouse_tail) { - *eventp = SP->_sysmouse_fifo[SP->_sysmouse_head]; + 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; + 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); + sp->_mouse_eventp = eventp = NEXT(eventp); result = TRUE; } break; @@ -719,10 +732,11 @@ _nc_mouse_inline(SCREEN *sp) { int b; bool result = FALSE; + MEVENT *eventp = sp->_mouse_eventp; TR(MY_TRACE, ("_nc_mouse_inline() called")); - if (SP->_mouse_type == M_XTERM) { + if (sp->_mouse_type == M_XTERM) { unsigned char kbuf[4]; mmask_t prev; size_t grabbed; @@ -760,7 +774,7 @@ _nc_mouse_inline(SCREEN *sp) * Wheel mice may return buttons 4 and 5 when the wheel is turned. * We encode those as button presses. */ - for (grabbed = 0; grabbed < 3; grabbed += res) { + for (grabbed = 0; grabbed < 3; grabbed += (size_t) res) { /* For VIO mouse we add extra bit 64 to disambiguate button-up. */ #if USE_EMX_MOUSE @@ -790,9 +804,9 @@ _nc_mouse_inline(SCREEN *sp) eventp->bstate = MASK_RELEASE(n) #else #define PRESS_POSITION(n) \ - eventp->bstate = (prev & MASK_PRESS(n) \ - ? REPORT_MOUSE_POSITION \ - : MASK_PRESS(n)) + eventp->bstate = (mmask_t) (prev & MASK_PRESS(n) \ + ? REPORT_MOUSE_POSITION \ + : MASK_PRESS(n)) #endif switch (kbuf[0] & 0x3) { @@ -856,11 +870,11 @@ _nc_mouse_inline(SCREEN *sp) eventp->y = (kbuf[2] - ' ') - 1; TR(MY_TRACE, ("_nc_mouse_inline: primitive mouse-event %s has slot %ld", - _tracemouse(eventp), - (long) (eventp - events))); + _nc_tracemouse(sp, eventp), + (long) IndexEV(sp, eventp))); /* bump the next-free pointer into the circular list */ - eventp = NEXT(eventp); + sp->_mouse_eventp = NEXT(eventp); #if 0 /* this return would be needed for QNX's mods to lib_getch.c */ return (TRUE); #endif @@ -870,36 +884,36 @@ _nc_mouse_inline(SCREEN *sp) } static void -mouse_activate(bool on) +mouse_activate(SCREEN *sp, bool on) { - if (!on && !initialized) + if (!on && !sp->_mouse_initialized) return; - if (!_nc_mouse_init()) + if (!_nc_mouse_init(sp)) return; if (on) { - switch (SP->_mouse_type) { + switch (sp->_mouse_type) { case M_XTERM: #if NCURSES_EXT_FUNCS keyok(KEY_MOUSE, on); #endif TPUTS_TRACE("xterm mouse initialization"); - enable_xterm_mouse(1); + enable_xterm_mouse(sp, 1); break; #if USE_GPM_SUPPORT case M_GPM: - if (enable_gpm_mouse(1)) { - SP->_mouse_fd = *my_gpm_fd; - T(("GPM mouse_fd %d", SP->_mouse_fd)); + if (enable_gpm_mouse(sp, 1)) { + sp->_mouse_fd = *(my_gpm_fd); + T(("GPM mouse_fd %d", sp->_mouse_fd)); } break; #endif #if USE_SYSMOUSE case M_SYSMOUSE: signal(SIGUSR2, handle_sysmouse); - SP->_mouse_active = TRUE; + sp->_mouse_active = TRUE; break; #endif case M_NONE: @@ -908,27 +922,27 @@ mouse_activate(bool on) /* 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; + 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) { + switch (sp->_mouse_type) { case M_XTERM: TPUTS_TRACE("xterm mouse deinitialization"); - enable_xterm_mouse(0); + enable_xterm_mouse(sp, 0); break; #if USE_GPM_SUPPORT case M_GPM: - enable_gpm_mouse(0); + enable_gpm_mouse(sp, 0); break; #endif #if USE_SYSMOUSE case M_SYSMOUSE: signal(SIGUSR2, SIG_IGN); - SP->_mouse_active = FALSE; + sp->_mouse_active = FALSE; break; #endif case M_NONE: @@ -945,9 +959,10 @@ mouse_activate(bool on) **************************************************************************/ static bool -_nc_mouse_parse(int runcount) +_nc_mouse_parse(SCREEN *sp, int runcount) /* parse a run of atomic mouse events into a gesture */ { + MEVENT *eventp = sp->_mouse_eventp; MEVENT *ep, *runp, *next, *prev = PREV(eventp); int n; int b; @@ -979,10 +994,10 @@ _nc_mouse_parse(int runcount) if (runcount == 1) { TR(MY_TRACE, ("_nc_mouse_parse: returning simple mouse event %s at slot %ld", - _tracemouse(prev), - (long) (prev - events))); + _nc_tracemouse(sp, prev), + (long) IndexEV(sp, prev))); return (prev->id >= NORMAL_EVENT) - ? ((prev->bstate & eventmask) ? TRUE : FALSE) + ? ((prev->bstate & sp->_mouse_mask) ? TRUE : FALSE) : FALSE; } @@ -993,12 +1008,12 @@ _nc_mouse_parse(int runcount) } #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) { - _trace_slot("before mouse press/release merge:"); + if (USE_TRACEF(TRACE_IEVENT)) { + _trace_slot(sp, "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, + RunParams(sp, eventp, runp), runcount); + _nc_unlock_global(tracef); } #endif /* TRACE */ @@ -1021,7 +1036,7 @@ _nc_mouse_parse(int runcount) #endif ) { for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((eventmask & MASK_CLICK(b)) + if ((sp->_mouse_mask & MASK_CLICK(b)) && (ep->bstate & MASK_PRESS(b))) { ep->bstate &= ~MASK_PRESS(b); ep->bstate |= MASK_CLICK(b); @@ -1036,12 +1051,12 @@ _nc_mouse_parse(int runcount) (merge); #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) { - _trace_slot("before mouse click merge:"); + if (USE_TRACEF(TRACE_IEVENT)) { + _trace_slot(sp, "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, + RunParams(sp, eventp, runp), runcount); + _nc_unlock_global(tracef); } #endif /* TRACE */ @@ -1077,7 +1092,7 @@ _nc_mouse_parse(int runcount) if ((ep->bstate & BUTTON_CLICKED) && (follower->bstate & BUTTON_CLICKED)) { for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((eventmask & MASK_DOUBLE_CLICK(b)) + if ((sp->_mouse_mask & MASK_DOUBLE_CLICK(b)) && (follower->bstate & MASK_CLICK(b))) { follower->bstate &= ~MASK_CLICK(b); follower->bstate |= MASK_DOUBLE_CLICK(b); @@ -1092,7 +1107,7 @@ _nc_mouse_parse(int runcount) if ((ep->bstate & BUTTON_DOUBLE_CLICKED) && (follower->bstate & BUTTON_CLICKED)) { for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((eventmask & MASK_TRIPLE_CLICK(b)) + if ((sp->_mouse_mask & MASK_TRIPLE_CLICK(b)) && (follower->bstate & MASK_CLICK(b))) { follower->bstate &= ~MASK_CLICK(b); follower->bstate |= MASK_TRIPLE_CLICK(b); @@ -1107,12 +1122,12 @@ _nc_mouse_parse(int runcount) (merge); #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) { - _trace_slot("before mouse event queue compaction:"); + if (USE_TRACEF(TRACE_IEVENT)) { + _trace_slot(sp, "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, + RunParams(sp, eventp, runp), runcount); + _nc_unlock_global(tracef); } #endif /* TRACE */ @@ -1121,23 +1136,23 @@ _nc_mouse_parse(int runcount) * don't match the current event mask. */ for (; runcount; prev = PREV(eventp), runcount--) - if (prev->id == INVALID_EVENT || !(prev->bstate & eventmask)) { - eventp = prev; + if (prev->id == INVALID_EVENT || !(prev->bstate & sp->_mouse_mask)) { + sp->_mouse_eventp = eventp = prev; } #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) { - _trace_slot("after mouse event queue compaction:"); + if (USE_TRACEF(TRACE_IEVENT)) { + _trace_slot(sp, "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, + RunParams(sp, eventp, runp), runcount); + _nc_unlock_global(tracef); } 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))); + _nc_tracemouse(sp, ep), + (long) IndexEV(sp, ep))); #endif /* TRACE */ /* after all this, do we have a valid event? */ @@ -1145,26 +1160,26 @@ _nc_mouse_parse(int runcount) } static void -_nc_mouse_wrap(SCREEN *sp GCC_UNUSED) +_nc_mouse_wrap(SCREEN *sp) /* release mouse -- called by endwin() before shellout/exit */ { TR(MY_TRACE, ("_nc_mouse_wrap() called")); - switch (SP->_mouse_type) { + switch (sp->_mouse_type) { case M_XTERM: - if (eventmask) - mouse_activate(FALSE); + if (sp->_mouse_mask) + mouse_activate(sp, FALSE); break; #if USE_GPM_SUPPORT /* GPM: pass all mouse events to next client */ case M_GPM: - if (eventmask) - mouse_activate(FALSE); + if (sp->_mouse_mask) + mouse_activate(sp, FALSE); break; #endif #if USE_SYSMOUSE case M_SYSMOUSE: - mouse_activate(FALSE); + mouse_activate(sp, FALSE); break; #endif case M_NONE: @@ -1173,29 +1188,29 @@ _nc_mouse_wrap(SCREEN *sp GCC_UNUSED) } static void -_nc_mouse_resume(SCREEN *sp GCC_UNUSED) +_nc_mouse_resume(SCREEN *sp) /* re-connect to mouse -- called by doupdate() after shellout */ { TR(MY_TRACE, ("_nc_mouse_resume() called")); - switch (SP->_mouse_type) { + switch (sp->_mouse_type) { case M_XTERM: /* xterm: re-enable reporting */ - if (eventmask) - mouse_activate(TRUE); + if (sp->_mouse_mask) + mouse_activate(sp, TRUE); break; #if USE_GPM_SUPPORT case M_GPM: /* GPM: reclaim our event set */ - if (eventmask) - mouse_activate(TRUE); + if (sp->_mouse_mask) + mouse_activate(sp, TRUE); break; #endif #if USE_SYSMOUSE case M_SYSMOUSE: - mouse_activate(TRUE); + mouse_activate(sp, TRUE); break; #endif case M_NONE: @@ -1209,13 +1224,13 @@ _nc_mouse_resume(SCREEN *sp GCC_UNUSED) * **************************************************************************/ -NCURSES_EXPORT(int) -getmouse(MEVENT * aevent) -/* grab a copy of the current mouse event */ +static int +_nc_getmouse(SCREEN *sp, MEVENT * aevent) { T((T_CALLED("getmouse(%p)"), aevent)); - if (aevent && (SP->_mouse_type != M_NONE)) { + if ((aevent != 0) && (sp != 0) && (sp->_mouse_type != M_NONE)) { + MEVENT *eventp = sp->_mouse_eventp; /* compute the current-event pointer */ MEVENT *prev = PREV(eventp); @@ -1223,8 +1238,8 @@ getmouse(MEVENT * aevent) *aevent = *prev; TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %ld", - _tracemouse(prev), - (long) (prev - events))); + _nc_tracemouse(sp, prev), + (long) IndexEV(sp, prev))); prev->id = INVALID_EVENT; /* so the queue slot becomes free */ returnCode(OK); @@ -1232,20 +1247,40 @@ getmouse(MEVENT * aevent) returnCode(ERR); } +/* grab a copy of the current mouse event */ NCURSES_EXPORT(int) -ungetmouse(MEVENT * aevent) -/* enqueue a synthesized mouse event to be seen by the next wgetch() */ +getmouse(MEVENT * aevent) +{ + return _nc_getmouse(SP, aevent); +} + +static int +_nc_ungetmouse(SCREEN *sp, MEVENT * aevent) { + int result = ERR; + T((T_CALLED("ungetmouse(%p)"), aevent)); - /* stick the given event in the next-free slot */ - *eventp = *aevent; + if (aevent != 0 && sp != 0) { + MEVENT *eventp = sp->_mouse_eventp; - /* bump the next-free pointer into the circular list */ - eventp = NEXT(eventp); + /* stick the given event in the next-free slot */ + *eventp = *aevent; + + /* bump the next-free pointer into the circular list */ + sp->_mouse_eventp = NEXT(eventp); - /* push back the notification event on the keyboard queue */ - returnCode(ungetch(KEY_MOUSE)); + /* push back the notification event on the keyboard queue */ + result = _nc_ungetch(sp, KEY_MOUSE); + } + returnCode(result); +} + +/* enqueue a synthesized mouse event to be seen by the next wgetch() */ +NCURSES_EXPORT(int) +ungetmouse(MEVENT * aevent) +{ + return _nc_ungetmouse(SP, aevent); } NCURSES_EXPORT(mmask_t) @@ -1256,27 +1291,30 @@ mousemask(mmask_t newmask, mmask_t * oldmask) 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; + if (SP != 0) { + if (oldmask) + *oldmask = SP->_mouse_mask; + + if (newmask || SP->_mouse_initialized) { + _nc_mouse_init(SP); + if (SP->_mouse_type != M_NONE) { + result = newmask & + (REPORT_MOUSE_POSITION + | BUTTON_ALT + | BUTTON_CTRL + | BUTTON_SHIFT + | BUTTON_PRESSED + | BUTTON_RELEASED + | BUTTON_CLICKED + | BUTTON_DOUBLE_CLICKED + | BUTTON_TRIPLE_CLICKED); + + mouse_activate(SP, (bool) (result != 0)); + + SP->_mouse_mask = result; + } + } } - returnBits(result); }