# 2006-09-12 # This patch makes MC use the mouse when built with ncurses. # Thomas Dickey # # ------------------------------------------------------------------------------ # key.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- # layout.c | 8 ++++++ # 2 files changed, 86 insertions(+), 3 deletions(-) # ------------------------------------------------------------------------------ Index: src/key.c --- mc-4.6.1+/src/key.c 2005-06-08 12:27:19.000000000 +0000 +++ mc-4.6.1-20060912/src/key.c 2006-09-12 20:40:11.000000000 +0000 @@ -488,6 +488,67 @@ static int clicks; static int last_btn = 0; +#if defined(USE_NCURSES) && defined(KEY_MOUSE) + MEVENT event; + int button; + + getmouse(&event); + ev->x = event.x + 1; + ev->y = event.y + 1; + ev->buttons = 0; + ev->type = 0; + + btn = -1; + for (button = 1; button <= 3; ++button) { + if (BUTTON_RELEASE(event.bstate, button)) { + btn = 3; + break; + } else if (BUTTON_PRESS(event.bstate, button)) { + btn = button - 1; + break; + } + } + + if (btn == 3){ + if (last_btn) { + ev->type = GPM_UP | (GPM_SINGLE << clicks); + ev->buttons = 0; + last_btn = 0; + GET_TIME (tv1); + clicks = 0; + } else { + /* Bogus event, maybe mouse wheel */ + ev->type = 0; + } + } else { + ev->type = GPM_DOWN; + GET_TIME (tv2); + if (tv1.tv_sec && (DIF_TIME (tv1,tv2) < double_click_speed)){ + clicks++; + clicks %= 3; + } else + clicks = 0; + + switch (btn) { + case 0: + ev->buttons = GPM_B_LEFT; + break; + case 1: + ev->buttons = GPM_B_MIDDLE; + break; + case 2: + ev->buttons = GPM_B_RIGHT; + break; + default: + /* Nothing */ + ev->type = 0; + ev->buttons = 0; + break; + } + last_btn = ev->buttons; + } +#else + /* Decode Xterm mouse information to a GPM style event */ /* Variable btn has following meaning: */ @@ -545,6 +606,7 @@ /* Transform them to 1-based */ ev->x = getch () - 32; ev->y = getch () - 32; +#endif } static key_def *create_sequence (const char *seq, int code, int action) @@ -756,9 +818,10 @@ return (mod | c); } -int get_key_code (int no_delay) +int get_key_code (int arg_delay) { int c; + int no_delay = (arg_delay > 0); static key_def *this = NULL, *parent; static struct timeval esctime = { -1, -1 }; static int lastnodelay = -1; @@ -795,6 +858,17 @@ if (c == KEY_RESIZE) goto nodelay_try_again; #endif +#if defined(USE_NCURSES) && defined(KEY_MOUSE) + if (c == KEY_MOUSE) { + if (arg_delay) { /* guess we're called from get_event() */ + return c; + } else { + MEVENT event; + getmouse(&event); + goto nodelay_try_again; + } + } +#endif if (no_delay) { nodelay (stdscr, FALSE); if (c == -1) { @@ -961,7 +1035,7 @@ try_channels (0); /* Try to get a character */ - c = get_key_code (0); + c = get_key_code (-1); if (c != -1) break; /* Failed -> wait 0.1 secs and try again */ @@ -1176,8 +1250,9 @@ keypad(stdscr, FALSE); /* disable intepreting keys by ncurses */ c = getch (); - while (c == -1) + while (c == -1) { c = getch (); /* Sanity check, should be unnecessary */ + } learn_store_key (buffer, &p, c); GET_TIME (endtime); endtime.tv_usec += LEARN_TIMEOUT; Index: src/layout.c --- mc-4.6.1+/src/layout.c 2005-05-27 14:19:18.000000000 +0000 +++ mc-4.6.1-20060912/src/layout.c 2006-09-12 21:20:49.000000000 +0000 @@ -598,6 +598,14 @@ keypad (stdscr, TRUE); nodelay (stdscr, FALSE); init_colors (); +#if defined(USE_NCURSES) && defined(KEY_MOUSE) + mouseinterval(0); + mousemask( + BUTTON1_RELEASED| BUTTON1_PRESSED | + BUTTON2_RELEASED| BUTTON2_PRESSED | + BUTTON3_RELEASED| BUTTON3_PRESSED , + (mmask_t *) 0); +#endif if (force_ugly_line_drawing) { for (i = 0; acs_approx[i].acscode != 0; i++) { acs_map[acs_approx[i].acscode] = acs_approx[i].character;