X-Git-Url: http://ncurses.scripts.mit.edu/?a=blobdiff_plain;f=ncurses%2Fbase%2Flib_mouse.c;h=d19189f7d6e97eac6555569ae780126949d05a36;hb=9fab8ab6b69130169a6880e63585d83efb1c1722;hp=e92be5b92fe0f8a716bf8876070aa6b4f1845284;hpb=1c2ec25b8186b7973aeb06ec4da6b63656e12f7d;p=ncurses.git diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index e92be5b9..d19189f7 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -79,7 +79,7 @@ #include -MODULE_ID("$Id: lib_mouse.c,v 1.98 2008/09/20 21:26:19 tom Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.104 2008/11/30 01:37:27 tom Exp $") #include #include @@ -255,13 +255,13 @@ mouse_server(unsigned long param) * 3 = middle. */ if ((mouev.fs ^ oldstate) & MOUSE_BN1_DOWN) - write_event(mouev.fs & MOUSE_BN1_DOWN, + write_event(sp, mouev.fs & MOUSE_BN1_DOWN, sp->_emxmouse_buttons[1], mouev.col, mouev.row); if ((mouev.fs ^ oldstate) & MOUSE_BN2_DOWN) - write_event(mouev.fs & MOUSE_BN2_DOWN, + write_event(sp, mouev.fs & MOUSE_BN2_DOWN, sp->_emxmouse_buttons[3], mouev.col, mouev.row); if ((mouev.fs ^ oldstate) & MOUSE_BN3_DOWN) - write_event(mouev.fs & MOUSE_BN3_DOWN, + write_event(sp, mouev.fs & MOUSE_BN3_DOWN, sp->_emxmouse_buttons[2], mouev.col, mouev.row); finish: @@ -365,45 +365,99 @@ enable_xterm_mouse(SCREEN *sp, int enable) } #if USE_GPM_SUPPORT -static int +static bool allow_gpm_mouse(void) { + bool result = FALSE; + /* GPM does printf's without checking if stdout is a terminal */ if (isatty(fileno(stdout))) { + char *list = getenv("NCURSES_GPM_TERMS"); char *env = getenv("TERM"); - /* GPM checks the beginning of the $TERM variable to decide if - * it should pass xterm events through. There is no real advantage - * in allowing GPM to do this. - */ - if (env == 0 || strncmp(env, "xterm", 5)) - return TRUE; + if (list != 0) { + if (env != 0) { + result = _nc_name_match(list, env, "|:"); + } + } else { + /* GPM checks the beginning of the $TERM variable to decide if it + * should pass xterm events through. There is no real advantage in + * allowing GPM to do this. Recent versions relax that check, and + * pretend that GPM can work with any terminal having the kmous + * capability. Perhaps that works for someone. If so, they can + * set the environment variable (above). + */ + if (env != 0 && strstr(env, "linux") != 0) { + result = TRUE; + } + } + } + return result; +} + +#ifdef HAVE_LIBDL +static void +unload_gpm_library(SCREEN *sp) +{ + if (SP->_dlopen_gpm != 0) { + T(("unload GPM library")); + sp->_mouse_gpm_loaded = FALSE; + sp->_mouse_fd = -1; + dlclose(sp->_dlopen_gpm); + sp->_dlopen_gpm = 0; + } +} + +static void +load_gpm_library(SCREEN *sp) +{ + sp->_mouse_gpm_found = FALSE; + 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())); + unload_gpm_library(sp); + } else { + sp->_mouse_gpm_found = TRUE; + sp->_mouse_gpm_loaded = TRUE; + } } - return FALSE; } +#endif static bool -enable_gpm_mouse(SCREEN *sp, int enable) +enable_gpm_mouse(SCREEN *sp, bool enable) { bool result; T((T_CALLED("enable_gpm_mouse(%d)"), enable)); if (enable && !sp->_mouse_active) { - /* GPM: initialize connection to gpm server */ - 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(&sp->_mouse_gpm_connect, 0) >= 0); +#ifdef HAVE_LIBDL + if (sp->_mouse_gpm_found && !sp->_mouse_gpm_loaded) { + load_gpm_library(sp); + } +#endif + if (sp->_mouse_gpm_loaded) { + /* GPM: initialize connection to gpm server */ + 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(&sp->_mouse_gpm_connect, 0) >= 0); + } else { + result = FALSE; + } sp->_mouse_active = result; T(("GPM open %s", result ? "succeeded" : "failed")); } else { @@ -413,15 +467,11 @@ enable_gpm_mouse(SCREEN *sp, int enable) sp->_mouse_active = FALSE; T(("GPM closed")); } - result = FALSE; + result = enable; } #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; + if (!result) { + unload_gpm_library(sp); } #endif returnBool(result); @@ -440,21 +490,11 @@ initialize_mousetype(SCREEN *sp) if (allow_gpm_mouse()) { 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(SP->_dlopen_gpm); - } else { - sp->_mouse_gpm_found = TRUE; - } - } + load_gpm_library(sp); #else /* !HAVE_LIBDL */ sp->_mouse_gpm_found = TRUE; -#endif sp->_mouse_gpm_loaded = TRUE; +#endif } /* @@ -505,7 +545,7 @@ initialize_mousetype(SCREEN *sp) setmode(handles[1], O_BINARY); /* Do not use CRT functions, we may single-threaded. */ rc = DosCreateThread((unsigned long *) &sp->_emxmouse_thread, - mouse_server, sp, 0, 8192); + mouse_server, (long) sp, 0, 8192); if (rc) { printf("mouse thread error %d=%#x", rc, rc); } else { @@ -654,11 +694,16 @@ _nc_mouse_event(SCREEN *sp GCC_UNUSED) #if USE_GPM_SUPPORT case M_GPM: - { + if (sp->_mouse_fd >= 0) { /* query server for event, return TRUE if we find one */ Gpm_Event ev; - if (my_Gpm_GetEvent(&ev) == 1) { + switch (my_Gpm_GetEvent(&ev)) { + case 0: + /* Connection closed, drop the mouse. */ + sp->_mouse_fd = -1; + break; + case 1: /* there's only one mouse... */ eventp->id = NORMAL_EVENT; @@ -691,6 +736,7 @@ _nc_mouse_event(SCREEN *sp GCC_UNUSED) /* bump the next-free pointer into the circular list */ sp->_mouse_eventp = eventp = NEXT(eventp); result = TRUE; + break; } } break; @@ -904,7 +950,7 @@ mouse_activate(SCREEN *sp, bool on) break; #if USE_GPM_SUPPORT case M_GPM: - if (enable_gpm_mouse(sp, 1)) { + if (enable_gpm_mouse(sp, TRUE)) { sp->_mouse_fd = *(my_gpm_fd); T(("GPM mouse_fd %d", sp->_mouse_fd)); } @@ -936,7 +982,7 @@ mouse_activate(SCREEN *sp, bool on) break; #if USE_GPM_SUPPORT case M_GPM: - enable_gpm_mouse(sp, 0); + enable_gpm_mouse(sp, FALSE); break; #endif #if USE_SYSMOUSE @@ -1357,10 +1403,16 @@ mouseinterval(int maxclick) /* This may be used by other routines to ask for the existence of mouse support */ -NCURSES_EXPORT(int) -_nc_has_mouse(void) +NCURSES_EXPORT(bool) +_nc_has_mouse(SCREEN *sp) +{ + return ((sp->_mouse_type == M_NONE) ? FALSE : TRUE); +} + +NCURSES_EXPORT(bool) +has_mouse(void) { - return (SP->_mouse_type == M_NONE ? 0 : 1); + return _nc_has_mouse(SP); } NCURSES_EXPORT(bool)