bmx-ng / sdl.mod

SDL backend for BlitzMax
7 stars 6 forks source link

Mousebuttons 3 and 2 (middle, right) are switched in SDL #11

Closed GWRon closed 7 years ago

GWRon commented 7 years ago

Run the following to see that mouse buttons are switched. vanilla: 1=left, 2=right, 3=middle NG with SDL: 1=left, 2=middle, 3=right

SuperStrict
'rem
'comment out to see difference
Framework Brl.StandardIO
Import SDL.SDLSystem
Import sdl.gl2sdlmax2d
SetGraphicsDriver GL2Max2DDriver()
'endrem
Graphics 800,600

Repeat
    If MouseHit(1) Then Print "Mouse 1 : " + MilliSecs()
    If MouseHit(2) Then Print "Mouse 2 : " + MilliSecs()
    If MouseHit(3) Then Print "Mouse 3 : " + MilliSecs()
Until KeyHit(KEY_ESCAPE)
GWRon commented 7 years ago

The reason is the following command in "brl,mod/system.mod/system.linux.c":

    case ButtonPress:
        data=xevent->xbutton.button;
        if (data==4)
        {
            id=BBEVENT_MOUSEWHEEL;
            data=1;
            break;
        }
        if (data==5)
        {
            id=BBEVENT_MOUSEWHEEL;
            data=-1;
            break;
        }
        id=BBEVENT_MOUSEDOWN;
        if (data>1) data=5-data;        if (data>1) data=5-data;

SDL behaves exactly as Xlib does (1=left, 2=middle, 3=right). But this line switches things except for left button: data=5 or 4 ? handled individually data=2 ? data becomes 5-2 = 3 data=3 ? data becomes 5-3 = 2 data=1 ? stays at 1

GWRon commented 7 years ago

I assume this is done to have consistent behaviour between Windows, Linux and Mac.

A potential fix is to open up sdl.mod/sdlsystem.mod/glue.c and replace

        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            bbSDLSystemEmitEvent( (event->type == SDL_MOUSEBUTTONDOWN) ? BBEVENT_MOUSEDOWN : BBEVENT_MOUSEUP,source,event->button.button,0,event->button.x,event->button.y,&bbNullObject );
            return;

with

        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            {
                //blitzmax has middle and right button switched
                int use_button = event->button.button;
                if (use_button == 2) {
                    use_button = 3;
                } else if (use_button == 3) {
                    use_button = 2;
                }
                bbSDLSystemEmitEvent( (event->type == SDL_MOUSEBUTTONDOWN) ? BBEVENT_MOUSEDOWN : BBEVENT_MOUSEUP,source,use_button,0,event->button.x,event->button.y,&bbNullObject );
                return;
            }

Alternatively - doing it like brl.system does:

        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            {
                //blitzmax has middle and right button switched using "5 - data"
                int use_button = event->button.button == 1 ? 1 : 5 - event->button.button;
                bbSDLSystemEmitEvent( (event->type == SDL_MOUSEBUTTONDOWN) ? BBEVENT_MOUSEDOWN : BBEVENT_MOUSEUP,source,use_button,0,event->button.x,event->button.y,&bbNullObject );
                return;
            }
GWRon commented 7 years ago

thanks - quick and efficiently done as usual