From b0accb87dfdc9331aa8cbc9f2a4d8a99e6a9485c Mon Sep 17 00:00:00 2001 From: deuce <> Date: Mon, 4 May 2020 18:32:54 +0000 Subject: [PATCH] Fix error where SDL mode would not get button up events. Add support for scroll "buttons" (buttons 4 and 5). --- src/conio/ciolib.h | 34 ++++++++++++++++++++++------ src/conio/curs_cio.c | 16 ++++++++++++- src/conio/mouse.c | 50 +++++++++++++++++++++++------------------ src/conio/sdl_con.c | 12 ++++++++++ src/conio/win32cio.c | 53 ++++++++++++++++++++++++++------------------ src/conio/x_events.c | 2 +- 6 files changed, 116 insertions(+), 51 deletions(-) diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h index b876748d06..bb77f4f912 100644 --- a/src/conio/ciolib.h +++ b/src/conio/ciolib.h @@ -568,11 +568,13 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable); #define CIOLIB_BUTTON_1 1 #define CIOLIB_BUTTON_2 2 #define CIOLIB_BUTTON_3 4 +#define CIOLIB_BUTTON_4 8 +#define CIOLIB_BUTTON_5 16 #define CIOLIB_BUTTON(x) (1<<(x-1)) enum { - CIOLIB_MOUSE_MOVE /* 0 */ + CIOLIB_MOUSE_MOVE /* 0 */ ,CIOLIB_BUTTON_1_PRESS ,CIOLIB_BUTTON_1_RELEASE ,CIOLIB_BUTTON_1_CLICK @@ -599,7 +601,25 @@ enum { ,CIOLIB_BUTTON_3_QUAD_CLICK ,CIOLIB_BUTTON_3_DRAG_START ,CIOLIB_BUTTON_3_DRAG_MOVE - ,CIOLIB_BUTTON_3_DRAG_END /* 27 */ + ,CIOLIB_BUTTON_3_DRAG_END + ,CIOLIB_BUTTON_4_PRESS + ,CIOLIB_BUTTON_4_RELEASE + ,CIOLIB_BUTTON_4_CLICK /* 30 */ + ,CIOLIB_BUTTON_4_DBL_CLICK + ,CIOLIB_BUTTON_4_TRPL_CLICK + ,CIOLIB_BUTTON_4_QUAD_CLICK + ,CIOLIB_BUTTON_4_DRAG_START + ,CIOLIB_BUTTON_4_DRAG_MOVE + ,CIOLIB_BUTTON_4_DRAG_END + ,CIOLIB_BUTTON_5_PRESS + ,CIOLIB_BUTTON_5_RELEASE + ,CIOLIB_BUTTON_5_CLICK + ,CIOLIB_BUTTON_5_DBL_CLICK /* 40 */ + ,CIOLIB_BUTTON_5_TRPL_CLICK + ,CIOLIB_BUTTON_5_QUAD_CLICK + ,CIOLIB_BUTTON_5_DRAG_START + ,CIOLIB_BUTTON_5_DRAG_MOVE + ,CIOLIB_BUTTON_5_DRAG_END /* 45 */ }; #define CIOLIB_BUTTON_PRESS(x) ((x-1)*9+1) @@ -628,11 +648,11 @@ CIOLIBEXPORT int CIOLIBCALL mouse_pending(void); CIOLIBEXPORT int CIOLIBCALL ciolib_getmouse(struct mouse_event *mevent); CIOLIBEXPORT int CIOLIBCALL ciolib_ungetmouse(struct mouse_event *mevent); CIOLIBEXPORT void ciolib_mouse_thread(void *data); -CIOLIBEXPORT int CIOLIBCALL ciomouse_setevents(int events); -CIOLIBEXPORT int CIOLIBCALL ciomouse_addevents(int events); -CIOLIBEXPORT int CIOLIBCALL ciomouse_delevents(int events); -CIOLIBEXPORT int CIOLIBCALL ciomouse_addevent(int event); -CIOLIBEXPORT int CIOLIBCALL ciomouse_delevent(int event); +CIOLIBEXPORT uint64_t CIOLIBCALL ciomouse_setevents(uint64_t events); +CIOLIBEXPORT uint64_t CIOLIBCALL ciomouse_addevents(uint64_t events); +CIOLIBEXPORT uint64_t CIOLIBCALL ciomouse_delevents(uint64_t events); +CIOLIBEXPORT uint64_t CIOLIBCALL ciomouse_addevent(uint64_t event); +CIOLIBEXPORT uint64_t CIOLIBCALL ciomouse_delevent(uint64_t event); #ifdef __cplusplus } #endif diff --git a/src/conio/curs_cio.c b/src/conio/curs_cio.c index 4bef3f5abe..ab5b1f9409 100644 --- a/src/conio/curs_cio.c +++ b/src/conio/curs_cio.c @@ -894,13 +894,19 @@ int curs_initciolib(long inmode) } mode = inmode; #ifdef NCURSES_VERSION_MAJOR - if(mousemask(BUTTON1_PRESSED|BUTTON1_RELEASED|BUTTON2_PRESSED|BUTTON2_RELEASED|BUTTON3_PRESSED|BUTTON3_RELEASED|REPORT_MOUSE_POSITION,NULL)==(BUTTON1_PRESSED|BUTTON1_RELEASED|BUTTON2_PRESSED|BUTTON2_RELEASED|BUTTON3_PRESSED|BUTTON3_RELEASED|REPORT_MOUSE_POSITION)) { + { + mmask_t msk = BUTTON1_PRESSED|BUTTON1_RELEASED|BUTTON2_PRESSED|BUTTON2_RELEASED|BUTTON3_PRESSED|BUTTON3_RELEASED|REPORT_MOUSE_POSITION; +#ifdef BUTTON5_PRESSED + msk |= BUTTON4_PRESSED|BUTTON5_PRESSED; +#endif + if (mousemask(msk, NULL) == msk) { mouseinterval(0); cio_api.mouse=1; } else { mousemask(0,NULL); } + } #endif if (COLORS >= 16) @@ -1139,6 +1145,14 @@ int curs_getch(void) case BUTTON3_RELEASED: evnt=CIOLIB_BUTTON_3_RELEASE; break; +#ifdef BUTTON5_PRESSED + case BUTTON4_PRESSED: + evnt=CIOLIB_BUTTON_4_PRESS; + break; + case BUTTON5_PRESSED: + evnt=CIOLIB_BUTTON_5_PRESS; + break; +#endif case REPORT_MOUSE_POSITION: evnt=CIOLIB_MOUSE_MOVE; break; diff --git a/src/conio/mouse.c b/src/conio/mouse.c index 9b1d782b68..5554c03bb5 100644 --- a/src/conio/mouse.c +++ b/src/conio/mouse.c @@ -80,10 +80,10 @@ struct mouse_state { int knownbuttonstatemask; /* Mask of buttons that have done something since * We started watching... the rest are actually in * an unknown state */ - int button_state[3]; /* Expanded state of each button */ - int button_x[3]; /* Start X/Y position of the current state */ - int button_y[3]; - clock_t timeout[3]; /* Button event timeouts (timespecs ie: time of expiry) */ + int button_state[5]; /* Expanded state of each button */ + int button_x[5]; /* Start X/Y position of the current state */ + int button_y[5]; + clock_t timeout[5]; /* Button event timeouts (timespecs ie: time of expiry) */ int curx; /* Current X position */ int cury; /* Current Y position */ int events; /* Currently enabled events */ @@ -95,7 +95,7 @@ struct mouse_state { }; struct mouse_state state; -int mouse_events=0; +uint64_t mouse_events=0; int ciolib_mouse_initialized=0; static int ungot=0; pthread_mutex_t unget_mutex; @@ -111,33 +111,33 @@ void CIOLIBCALL init_mouse(void) ciolib_mouse_initialized=1; } -int CIOLIBCALL ciomouse_setevents(int events) +uint64_t CIOLIBCALL ciomouse_setevents(uint64_t events) { mouse_events=events; return mouse_events; } -int CIOLIBCALL ciomouse_addevents(int events) +uint64_t CIOLIBCALL ciomouse_addevents(uint64_t events) { mouse_events |= events; return mouse_events; } -int CIOLIBCALL ciomouse_delevents(int events) +uint64_t CIOLIBCALL ciomouse_delevents(uint64_t events) { mouse_events &= ~events; return mouse_events; } -int CIOLIBCALL ciomouse_addevent(int event) +uint64_t CIOLIBCALL ciomouse_addevent(uint64_t event) { - mouse_events |= (1<<event); + mouse_events |= (UINT64_C(1)<<event); return mouse_events; } -int CIOLIBCALL ciomouse_delevent(int event) +uint64_t CIOLIBCALL ciomouse_delevent(uint64_t event) { - mouse_events &= ~(1<<event); + mouse_events &= ~(UINT64_C(1)<<event); return mouse_events; } @@ -164,7 +164,7 @@ void CIOLIBCALL add_outevent(int event, int x, int y) struct out_mouse_event *ome; int but; - if(!(mouse_events & 1<<event)) + if(!(mouse_events & UINT64_C(1)<<event)) return; ome=(struct out_mouse_event *)malloc(sizeof(struct out_mouse_event)); @@ -187,19 +187,19 @@ int CIOLIBCALL more_multies(int button, int clicks) { switch(clicks) { case 0: - if(mouse_events & (1<<CIOLIB_BUTTON_CLICK(button))) + if(mouse_events & (UINT64_C(1)<<CIOLIB_BUTTON_CLICK(button))) return(1); /* Fall-through */ case 1: - if(mouse_events & (1<<CIOLIB_BUTTON_DBL_CLICK(button))) + if(mouse_events & (UINT64_C(1)<<CIOLIB_BUTTON_DBL_CLICK(button))) return(1); /* Fall-through */ case 2: - if(mouse_events & (1<<CIOLIB_BUTTON_TRPL_CLICK(button))) + if(mouse_events & (UINT64_C(1)<<CIOLIB_BUTTON_TRPL_CLICK(button))) return(1); /* Fall-through */ case 3: - if(mouse_events & (1<<CIOLIB_BUTTON_QUAD_CLICK(button))) + if(mouse_events & (UINT64_C(1)<<CIOLIB_BUTTON_QUAD_CLICK(button))) return(1); /* Fall-through */ } @@ -280,13 +280,18 @@ void ciolib_mouse_thread(void *data) continue; } but=CIOLIB_BUTTON_NUMBER(in->event); + if (in->x < 0) + in->x = state.curx; + if (in->y < 0) + in->y = state.curx; + switch(CIOLIB_BUTTON_BASE(in->event)) { case CIOLIB_MOUSE_MOVE: if(in->x==state.curx && in->y==state.cury) break; add_outevent(CIOLIB_MOUSE_MOVE,in->x,in->y); - for(but=1;but<=3;but++) { + for(but=1;but<=5;but++) { switch(state.button_state[but-1]) { case MOUSE_NOSTATE: if(state.buttonstate & CIOLIB_BUTTON(but)) { @@ -354,6 +359,9 @@ void ciolib_mouse_thread(void *data) state.button_state[but-1]=MOUSE_NOSTATE; state.timeout[but-1]=0; } + // Scroll "buttons"... + if (but > 3) + state.button_state[but-1] = MOUSE_NOSTATE; break; case MOUSE_CLICKED: state.button_state[but-1]=MOUSE_DOUBLEPRESSED; @@ -427,13 +435,13 @@ void ciolib_mouse_thread(void *data) } timeout_button=0; - for(but=1;but<=3;but++) { + for(but=1;but<=5;but++) { if(state.button_state[but-1]==MOUSE_DRAGSTARTED && - (mouse_events & ((1<<CIOLIB_BUTTON_DRAG_START(but)) | (1<<CIOLIB_BUTTON_DRAG_MOVE(but)) | (1<<CIOLIB_BUTTON_DRAG_END(but)))) == 0) + (mouse_events & ((UINT64_C(1)<<CIOLIB_BUTTON_DRAG_START(but)) | (UINT64_C(1)<<CIOLIB_BUTTON_DRAG_MOVE(but)) | (UINT64_C(1)<<CIOLIB_BUTTON_DRAG_END(but)))) == 0) state.button_state[but-1] = MOUSE_NOSTATE; } - for(but=1;but<=3;but++) { + for(but=1;but<=5;but++) { if(state.button_state[but-1]!=MOUSE_NOSTATE && state.button_state[but-1]!=MOUSE_DRAGSTARTED && state.timeout[but-1]!=0 diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c index 9957a716c8..382e9e6d13 100644 --- a/src/conio/sdl_con.c +++ b/src/conio/sdl_con.c @@ -863,6 +863,18 @@ void sdl_video_event_thread(void *data) break; } break; + case SDL_MOUSEWHEEL: + if (!ciolib_mouse_initialized) + break; + if (ev.wheel.y) { + if (ev.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) + ev.wheel.y = 0 - ev.wheel.y; + if (ev.wheel.y > 0) + ciomouse_gotevent(CIOLIB_BUTTON_PRESS(4), -1, -1); + if (ev.wheel.y < 0) + ciomouse_gotevent(CIOLIB_BUTTON_PRESS(5), -1, -1); + } + break; case SDL_MOUSEBUTTONUP: if(!ciolib_mouse_initialized) break; diff --git a/src/conio/win32cio.c b/src/conio/win32cio.c index a51a172398..2fe63d0e41 100644 --- a/src/conio/win32cio.c +++ b/src/conio/win32cio.c @@ -334,28 +334,39 @@ static int win32_keyboardio(int isgetch) LastY=input.Event.MouseEvent.dwMousePosition.Y+1; ciomouse_gotevent(CIOLIB_MOUSE_MOVE,LastX,LastY); } - if(last_state != input.Event.MouseEvent.dwButtonState) { - switch(input.Event.MouseEvent.dwButtonState ^ last_state) { - case FROM_LEFT_1ST_BUTTON_PRESSED: - if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) - ciomouse_gotevent(CIOLIB_BUTTON_1_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - else - ciomouse_gotevent(CIOLIB_BUTTON_1_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - break; - case FROM_LEFT_2ND_BUTTON_PRESSED: - if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) - ciomouse_gotevent(CIOLIB_BUTTON_2_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - else - ciomouse_gotevent(CIOLIB_BUTTON_2_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - break; - case RIGHTMOST_BUTTON_PRESSED: - if(input.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) - ciomouse_gotevent(CIOLIB_BUTTON_3_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - else - ciomouse_gotevent(CIOLIB_BUTTON_3_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); - break; + if (input.Event.MouseEvent.dwEventFlags == 0) { + if(last_state != input.Event.MouseEvent.dwButtonState) { + switch(input.Event.MouseEvent.dwButtonState ^ last_state) { + case FROM_LEFT_1ST_BUTTON_PRESSED: + if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) + ciomouse_gotevent(CIOLIB_BUTTON_1_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + else + ciomouse_gotevent(CIOLIB_BUTTON_1_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + break; + case FROM_LEFT_2ND_BUTTON_PRESSED: + if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) + ciomouse_gotevent(CIOLIB_BUTTON_2_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + else + ciomouse_gotevent(CIOLIB_BUTTON_2_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + break; + case RIGHTMOST_BUTTON_PRESSED: + if(input.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) + ciomouse_gotevent(CIOLIB_BUTTON_3_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + else + ciomouse_gotevent(CIOLIB_BUTTON_3_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + break; + } + last_state=input.Event.MouseEvent.dwButtonState; + } + } + else if (input.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED) { + // If the high word of the dwButtonState member contains a positive value... ARGH! + if (input.Event.MouseEvent.dwButtonState & 0x80000000) { + ciomouse_gotevent(CIOLIB_BUTTON_5_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); + } + else { + ciomouse_gotevent(CIOLIB_BUTTON_4_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); } - last_state=input.Event.MouseEvent.dwButtonState; } } } diff --git a/src/conio/x_events.c b/src/conio/x_events.c index 2e7af59797..425866d12f 100644 --- a/src/conio/x_events.c +++ b/src/conio/x_events.c @@ -818,7 +818,7 @@ static int x11_event(XEvent *ev) be->x=x_cvstat.cols; if(be->y>x_cvstat.rows+1) be->y=x_cvstat.rows+1; - if (be->button <= 3) { + if (be->button <= 5) { ciomouse_gotevent(CIOLIB_BUTTON_PRESS(be->button),be->x,be->y); } } -- GitLab