Esempio n. 1
0
static void handlePointerButton(_GLFWwindow* window,
                              int pressed,
                              const MirPointerEvent* pointer_event)
{
    MirPointerButton button = mir_pointer_event_buttons  (pointer_event);
    int mods                = mir_pointer_event_modifiers(pointer_event);
    const int publicMods    = mirModToGLFWMod(mods);
    int publicButton;

    switch (button)
    {
        case mir_pointer_button_primary:
            publicButton = GLFW_MOUSE_BUTTON_LEFT;
            break;
        case mir_pointer_button_secondary:
            publicButton = GLFW_MOUSE_BUTTON_RIGHT;
            break;
        case mir_pointer_button_tertiary:
            publicButton = GLFW_MOUSE_BUTTON_MIDDLE;
            break;
        case mir_pointer_button_forward:
            // FIXME What is the forward button?
            publicButton = GLFW_MOUSE_BUTTON_4;
            break;
        case mir_pointer_button_back:
            // FIXME What is the back button?
            publicButton = GLFW_MOUSE_BUTTON_5;
            break;
        default:
            break;
    }

    _glfwInputMouseClick(window, publicButton, pressed, publicMods);
}
Esempio n. 2
0
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{
    if (window->callbacks.focus)
        window->callbacks.focus((GLFWwindow*) window, focused);

    if (!focused)
    {
        int key, button;

        for (key = 0;  key <= GLFW_KEY_LAST;  key++)
        {
            if (window->keys[key] == GLFW_PRESS)
            {
                const int scancode = _glfwPlatformGetKeyScancode(key);
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, 0);
            }
        }

        for (button = 0;  button <= GLFW_MOUSE_BUTTON_LAST;  button++)
        {
            if (window->mouseButtons[button] == GLFW_PRESS)
                _glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
        }
    }
}
static void handleMouseButton(_GLFWwindow* window,
                              int pressed, int mods, MirMotionButton button)
{
    static int lastButton;
    int publicButton;
    const int publicMods = mirModToGLFWMod(mods);

    switch (button)
    {
        case mir_motion_button_primary:
            publicButton = GLFW_MOUSE_BUTTON_LEFT;
            break;
        case mir_motion_button_secondary:
            publicButton = GLFW_MOUSE_BUTTON_RIGHT;
            break;
        case mir_motion_button_tertiary:
            publicButton = GLFW_MOUSE_BUTTON_MIDDLE;
            break;
        case mir_motion_button_forward:
            // FIXME What is the forward button?
            publicButton = GLFW_MOUSE_BUTTON_4;
            break;
        case mir_motion_button_back:
            // FIXME What is the back button?
            publicButton = GLFW_MOUSE_BUTTON_5;
            break;
        default:
            publicButton = lastButton;
            break;
    }

    lastButton = publicButton;

    _glfwInputMouseClick(window, publicButton, pressed, publicMods);
}
Esempio n. 4
0
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{
    if (focused)
    {
        _glfw.cursorWindow = window;

        if (window->callbacks.focus)
            window->callbacks.focus((GLFWwindow*) window, focused);
    }
    else
    {
        int i;

        _glfw.cursorWindow = NULL;

        if (window->callbacks.focus)
            window->callbacks.focus((GLFWwindow*) window, focused);

        // Release all pressed keyboard keys
        for (i = 0;  i <= GLFW_KEY_LAST;  i++)
        {
            if (window->keys[i] == GLFW_PRESS)
                _glfwInputKey(window, i, 0, GLFW_RELEASE, 0);
        }

        // Release all pressed mouse buttons
        for (i = 0;  i <= GLFW_MOUSE_BUTTON_LAST;  i++)
        {
            if (window->mouseButtons[i] == GLFW_PRESS)
                _glfwInputMouseClick(window, i, GLFW_RELEASE, 0);
        }
    }
}
Esempio n. 5
0
static void handlePointerButton(_GLFWwindow* window,
                              int pressed,
                              const MirPointerEvent* pointer_event)
{
    int mods                = mir_pointer_event_modifiers(pointer_event);
    const int publicMods    = mirModToGLFWMod(mods);
    MirPointerButton button = mir_pointer_button_primary;
    static uint32_t oldButtonStates = 0;
    uint32_t newButtonStates        = mir_pointer_event_buttons(pointer_event);
    int publicButton                = GLFW_MOUSE_BUTTON_LEFT;

    // XOR our old button states our new states to figure out what was added or removed
    button = newButtonStates ^ oldButtonStates;

    switch (button)
    {
        case mir_pointer_button_primary:
            publicButton = GLFW_MOUSE_BUTTON_LEFT;
            break;
        case mir_pointer_button_secondary:
            publicButton = GLFW_MOUSE_BUTTON_RIGHT;
            break;
        case mir_pointer_button_tertiary:
            publicButton = GLFW_MOUSE_BUTTON_MIDDLE;
            break;
        case mir_pointer_button_forward:
            // FIXME What is the forward button?
            publicButton = GLFW_MOUSE_BUTTON_4;
            break;
        case mir_pointer_button_back:
            // FIXME What is the back button?
            publicButton = GLFW_MOUSE_BUTTON_5;
            break;
        default:
            break;
    }

    oldButtonStates = newButtonStates;

    _glfwInputMouseClick(window, publicButton, pressed, publicMods);
}
Esempio n. 6
0
void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused)
{
    if (focused)
    {
        if (_glfwLibrary.focusedWindow != window)
        {
            _glfwLibrary.focusedWindow = window;

            if (window->windowFocusCallback)
                window->windowFocusCallback(window, focused);
        }
    }
    else
    {
        if (_glfwLibrary.focusedWindow == window)
        {
            int i;

            // Release all pressed keyboard keys
            for (i = 0;  i <= GLFW_KEY_LAST;  i++)
            {
                if (window->key[i] == GLFW_PRESS)
                    _glfwInputKey(window, i, GLFW_RELEASE);
            }

            // Release all pressed mouse buttons
            for (i = 0;  i <= GLFW_MOUSE_BUTTON_LAST;  i++)
            {
                if (window->mouseButton[i] == GLFW_PRESS)
                    _glfwInputMouseClick(window, i, GLFW_RELEASE);
            }

            _glfwLibrary.focusedWindow = NULL;

            if (window->windowFocusCallback)
                window->windowFocusCallback(window, focused);
        }
    }
}
Esempio n. 7
0
void _glfwInputDeactivation( void )
{
    int i;

    // Release all keyboard keys
    for( i = 0; i <= GLFW_KEY_LAST; i ++ )
    {
        if( _glfwInput.Key[ i ] == GLFW_PRESS )
        {
            _glfwInputKey( i, GLFW_RELEASE );
        }
    }

    // Release all mouse buttons
    for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ )
    {
        if( _glfwInput.MouseButton[ i ] == GLFW_PRESS )
        {
            _glfwInputMouseClick( i, GLFW_RELEASE );
        }
    }
}
Esempio n. 8
0
static void pointerHandleButton(void* data,
                                struct wl_pointer* wl_pointer,
                                uint32_t serial,
                                uint32_t time,
                                uint32_t button,
                                uint32_t state)
{
    _GLFWwindow* window = _glfw.wl.pointerFocus;
    int glfwButton;

    if (!window)
        return;

    /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
     * codes. */
    glfwButton = button - BTN_LEFT;

    _glfwInputMouseClick(window,
                         glfwButton,
                         state == WL_POINTER_BUTTON_STATE_PRESSED
                                ? GLFW_PRESS
                                : GLFW_RELEASE,
                         _glfw.wl.xkb.modifiers);
}
Esempio n. 9
0
static int _glfwProcessEvents( void )
{
    struct IntuiMessage message, *tmp_message = NULL;
    struct MsgPort      *msg_port;
    int                 win_closed = GL_FALSE, action;
    int                 x, y;

    // Examine pending messages
    msg_port = _glfwWin.Window->UserPort;
    while( (tmp_message = (struct IntuiMessage *) GetMsg( msg_port )) )
    {
        // Copy contents of message structure
        message = *tmp_message;

        // Now reply to the message (we don't need it anymore)
        ReplyMsg( (struct Message *) tmp_message );

        // Handle different messages
        switch( message.Class )
        {

        // Was the window activated?
        case IDCMP_ACTIVEWINDOW:
            _glfwWin.Active = GL_TRUE;
            break;

        // Was the window deactivated?
        case IDCMP_INACTIVEWINDOW:
            _glfwWin.Active = GL_FALSE;
	    _glfwInputDeactivation();
            break;

        // Did we get a keyboard press or release?
        case IDCMP_RAWKEY:
            action = (message.Code & 0x80) ? GLFW_RELEASE : GLFW_PRESS;
            message.Code &= 0x7F;
            _glfwInputKey( _glfwTranslateKey( &message ), action );
            _glfwInputChar( _glfwTranslateChar( &message ), action );
            break;

        // Was the mouse moved?
        case IDCMP_MOUSEMOVE:
            x = message.MouseX;
            y = message.MouseY;
            if( _glfwWin.PointerHidden )
            {
                // When pointer is hidden, we get delta moves
                x += _glfwInput.MousePosX;
                y += _glfwInput.MousePosY;
            }
            else if( x < 0 || x >= _glfwWin.Width ||
                     y < 0 || y >= _glfwWin.Height )
            {
                // Only report mouse moves that are INSIDE client area
                break;
            }
            if( x != _glfwInput.MousePosX || y != _glfwInput.MousePosY )
            {
                _glfwInput.MousePosX = x;
                _glfwInput.MousePosY = y;
                if( _glfwWin.MousePosCallback )
                {
                    _glfwWin.MousePosCallback( x, y );
                }
            }
            break;

        // Did we get a mouse button event?
        case IDCMP_MOUSEBUTTONS:
            switch( message.Code )
            {
            case SELECTUP:
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
                                      GLFW_RELEASE );
                break;
            case SELECTDOWN:
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
                                      GLFW_PRESS );
                break;
            case MENUUP:
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
                                      GLFW_RELEASE );
                break;
            case MENUDOWN:
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
                                      GLFW_PRESS );
                break;
            default:
                break;
            }
            break;

        // Was the window size changed?
        case IDCMP_NEWSIZE:
            _glfwWin.Width  = message.IDCMPWindow->GZZWidth;
            _glfwWin.Height = message.IDCMPWindow->GZZHeight;
            if( _glfwWin.WindowSizeCallback )
            {
                _glfwWin.WindowSizeCallback( _glfwWin.Width,
                                             _glfwWin.Height );
            }
            break;

        // Was the window contents damaged?
        case IDCMP_REFRESHWINDOW:
            // Intuition wants us to do this...
            BeginRefresh( _glfwWin.Window );
            EndRefresh( _glfwWin.Window, TRUE );

            // Call user callback function
            if( _glfwWin.WindowRefreshCallback )
            {
                _glfwWin.WindowRefreshCallback();
            }
            break;

        // Was the window closed?
        case IDCMP_CLOSEWINDOW:
            win_closed = GL_TRUE;
            break;

        default:
            break;
        }
    }

    // Return GL_TRUE if window was closed
    return( win_closed );
}
Esempio n. 10
0
LRESULT CALLBACK _glfwWindowCallback( HWND hWnd, UINT uMsg,
     WPARAM wParam, LPARAM lParam )
{
    int WheelDelta, Iconified;


	// ZBS added this code to look for the correct _glfwWin given the hWnd
	// Changed all the references from _glfwWin. to winPtr->
	_GLFWwin *winPtr = 0;
	int i;
	for( i=0; i<MAX_ALIASES; i++ ) {
		if( aliases[i].Wnd == hWnd ) {
			winPtr = &aliases[i];
			break;
		}
	}
	if( winPtr == 0 ) {
		winPtr = &_glfwWin;
	}


    // Handle certain window messages
    switch( uMsg )
    {
        // Window activate message? (iconification?)
        case WM_ACTIVATE:
            winPtr->Active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE :
                                                              GL_FALSE;
            Iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;

            // Were we deactivated/iconified?
            if( (!winPtr->Active || Iconified) && !winPtr->Iconified )
            {
                // If we are in fullscreen mode we need to iconify
                if( winPtr->Fullscreen )
                {
                    // Do we need to manually iconify?
                    if( !Iconified )
                    {
                        // Minimize window
                        CloseWindow( winPtr->Wnd );

                        // The window is now iconified
                        Iconified = GL_TRUE;
                    }

                    // Change display settings to the desktop resolution
                    ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
                }

                // Unlock mouse
                if( !winPtr->OldMouseLockValid )
                {
                    winPtr->OldMouseLock = winPtr->MouseLock;
                    winPtr->OldMouseLockValid = GL_TRUE;
                    glfwEnable( GLFW_MOUSE_CURSOR );
                }
            }
            else if( winPtr->Active || !Iconified )
            {
                // If we are in fullscreen mode we need to maximize
                if( winPtr->Fullscreen && winPtr->Iconified )
                {
                    // Change display settings to the user selected mode
                    _glfwSetVideoModeMODE( winPtr->ModeID );

                    // Do we need to manually restore window?
                    if( Iconified )
                    {
                        // Restore window
                        OpenIcon( winPtr->Wnd );

                        // The window is no longer iconified
                        Iconified = GL_FALSE;

                        // Activate window
                        ShowWindow( hWnd, SW_SHOW );
                        _glfwSetForegroundWindow( winPtr->Wnd );
                        SetFocus( winPtr->Wnd );
                    }
                }

                // Lock mouse, if necessary
                if( winPtr->OldMouseLockValid && winPtr->OldMouseLock )
                {
                    glfwDisable( GLFW_MOUSE_CURSOR );
                }
                winPtr->OldMouseLockValid = GL_FALSE;
            }

            winPtr->Iconified = Iconified;
            return 0;

        // Intercept system commands (forbid certain actions/events)
        case WM_SYSCOMMAND:
            switch( wParam )
            {
                // Screensaver trying to start or monitor trying to enter
                // powersave?
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:
                    if( winPtr->Fullscreen )
                    {
                        return 0;
                    }
                    else
                    {
                        break;
                    }

                // User trying to access application menu using ALT?
                case SC_KEYMENU:
                    return 0;
            }
            break;

        // Did we receive a close message?
        case WM_CLOSE:
            PostQuitMessage( 0 );
            return 0;

        // Is a key being pressed?
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
            // Translate and report key press
            _glfwInputKey( _glfwTranslateKey( wParam, lParam ),
                           GLFW_PRESS );

            // Translate and report character input
            if( winPtr->CharCallback )
            {
                _glfwTranslateChar( wParam, lParam, GLFW_PRESS );
            }
            return 0;

        // Is a key being released?
        case WM_KEYUP:
        case WM_SYSKEYUP:
            // Special trick: release both shift keys on SHIFT up event
            if( wParam == VK_SHIFT )
            {
                _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );
                _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );
            }
            else
            {
                // Translate and report key release
                _glfwInputKey( _glfwTranslateKey( wParam, lParam ),
                               GLFW_RELEASE );
            }

            // Translate and report character input
            if( winPtr->CharCallback )
            {
                _glfwTranslateChar( wParam, lParam, GLFW_RELEASE );
            }
            return 0;

        // Were any of the mouse-buttons pressed?
        case WM_LBUTTONDOWN:
            SetCapture(hWnd);
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );
            return 0;
        case WM_RBUTTONDOWN:
            SetCapture(hWnd);
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );
            return 0;
        case WM_MBUTTONDOWN:
            SetCapture(hWnd);
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );
            return 0;
        case WM_XBUTTONDOWN:
            if( HIWORD(wParam) == XBUTTON1 )
            {
                SetCapture(hWnd);
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_PRESS );
            }
            else if( HIWORD(wParam) == XBUTTON2 )
            {
                SetCapture(hWnd);
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_PRESS );
            }
            return 1;

        // Were any of the mouse-buttons released?
        case WM_LBUTTONUP:
            ReleaseCapture();
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );
            return 0;
        case WM_RBUTTONUP:
            ReleaseCapture();
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );
            return 0;
        case WM_MBUTTONUP:
            ReleaseCapture();
            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE );
            return 0;
        case WM_XBUTTONUP:
            if( HIWORD(wParam) == XBUTTON1 )
            {
                ReleaseCapture();
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_RELEASE );
            }
            else if( HIWORD(wParam) == XBUTTON2 )
            {
                ReleaseCapture();
                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_RELEASE );
            }
            return 1;

        // Did the mouse move?
        case WM_MOUSEMOVE:
            {
                int NewMouseX, NewMouseY;

                // Get signed (!) mouse position
                NewMouseX = (int)((short)LOWORD(lParam));
                NewMouseY = (int)((short)HIWORD(lParam));

                if( NewMouseX != _glfwInput.OldMouseX ||
                    NewMouseY != _glfwInput.OldMouseY )
                {
                    if( winPtr->MouseLock )
                    {
                        _glfwInput.MousePosX += NewMouseX -
                                                _glfwInput.OldMouseX;
                        _glfwInput.MousePosY += NewMouseY -
                                                _glfwInput.OldMouseY;
                    }
                    else
                    {
                        _glfwInput.MousePosX = NewMouseX;
                        _glfwInput.MousePosY = NewMouseY;
                    }
                    _glfwInput.OldMouseX = NewMouseX;
                    _glfwInput.OldMouseY = NewMouseY;
                    _glfwInput.MouseMoved = GL_TRUE;
    
                    // Call user callback function
                    if( winPtr->MousePosCallback )
                    {
                        winPtr->MousePosCallback( _glfwInput.MousePosX,
                                                   _glfwInput.MousePosY );
                    }
                }
            }
            return 0;

        // Mouse wheel action?
        case WM_MOUSEWHEEL:
            // WM_MOUSEWHEEL is not supported under Windows 95
            if( _glfwSys.WinVer != _GLFW_WIN_95 )
            {
                WheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA;
                _glfwInput.WheelPos += WheelDelta;
                if( winPtr->MouseWheelCallback )
                {
                    winPtr->MouseWheelCallback( _glfwInput.WheelPos );
                }
                return 0;
            }
            break;

        // Resize the window?
        case WM_SIZE:
            winPtr->Width  = LOWORD(lParam);
            winPtr->Height = HIWORD(lParam);
            if( winPtr->WindowSizeCallback )
            {
                winPtr->WindowSizeCallback( LOWORD(lParam),
                                             HIWORD(lParam) );
            }
            return 0;

        // Was the window contents damaged?
        case WM_PAINT:
            // Call user callback function
            if( winPtr->WindowRefreshCallback )
            {
                winPtr->WindowRefreshCallback();
            }
            break;

        default:
            break;
    }
// Window callback function (handles window events)
//
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam)
{
    _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0);

    switch (uMsg)
    {
        case WM_NCCREATE:
        {
            CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam;
            SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams);
            break;
        }

        case WM_SETFOCUS:
        {
            if (window->cursorMode != GLFW_CURSOR_NORMAL)
                _glfwPlatformApplyCursorMode(window);

            if (window->monitor && window->autoIconify)
                enterFullscreenMode(window);

            _glfwInputWindowFocus(window, GL_TRUE);
            return 0;
        }

        case WM_KILLFOCUS:
        {
            if (window->cursorMode != GLFW_CURSOR_NORMAL)
                restoreCursor(window);

            if (window->monitor && window->autoIconify)
            {
                _glfwPlatformIconifyWindow(window);
                leaveFullscreenMode(window);
            }

            _glfwInputWindowFocus(window, GL_FALSE);
            return 0;
        }

        case WM_SYSCOMMAND:
        {
            switch (wParam & 0xfff0)
            {
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:
                {
                    if (window->monitor)
                    {
                        // We are running in full screen mode, so disallow
                        // screen saver and screen blanking
                        return 0;
                    }
                    else
                        break;
                }

                // User trying to access application menu using ALT?
                case SC_KEYMENU:
                    return 0;
            }
            break;
        }

        case WM_CLOSE:
        {
            _glfwInputWindowCloseRequest(window);
            return 0;
        }

        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        {
            const int scancode = (lParam >> 16) & 0x1ff;
            const int key = translateKey(wParam, lParam);
            if (key == _GLFW_KEY_INVALID)
                break;

            _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods());
            break;
        }

        case WM_CHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return 0;
        }

        case WM_SYSCHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE);
            return 0;
        }

        case WM_UNICHAR:
        {
            // This message is not sent by Windows, but is sent by some
            // third-party input method engines

            if (wParam == UNICODE_NOCHAR)
            {
                // Returning TRUE here announces support for this message
                return TRUE;
            }

            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return FALSE;
        }

        case WM_KEYUP:
        case WM_SYSKEYUP:
        {
            const int mods = getKeyMods();
            const int scancode = (lParam >> 16) & 0x1ff;
            const int key = translateKey(wParam, lParam);
            if (key == _GLFW_KEY_INVALID)
                break;

            if (wParam == VK_SHIFT)
            {
                // Release both Shift keys on Shift up event, as only one event
                // is sent even if both keys are released
                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
            }
            else if (wParam == VK_SNAPSHOT)
            {
                // Key down is not reported for the print screen key
                _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
            }
            else
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);

            break;
        }

        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:
        case WM_XBUTTONDOWN:
        {
            const int mods = getKeyMods();

            SetCapture(hWnd);

            if (uMsg == WM_LBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
            else if (uMsg == WM_RBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
            else if (uMsg == WM_MBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
            else
            {
                if (HIWORD(wParam) == XBUTTON1)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods);
                else if (HIWORD(wParam) == XBUTTON2)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods);

                return TRUE;
            }

            return 0;
        }

        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
        case WM_MBUTTONUP:
        case WM_XBUTTONUP:
        {
            const int mods = getKeyMods();

            ReleaseCapture();

            if (uMsg == WM_LBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods);
            else if (uMsg == WM_RBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods);
            else if (uMsg == WM_MBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods);
            else
            {
                if (HIWORD(wParam) == XBUTTON1)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods);
                else if (HIWORD(wParam) == XBUTTON2)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods);

                return TRUE;
            }

            return 0;
        }

        case WM_MOUSEMOVE:
        {
            const int x = GET_X_LPARAM(lParam);
            const int y = GET_Y_LPARAM(lParam);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
            {
                if (_glfw.focusedWindow != window)
                    break;

                _glfwInputCursorMotion(window,
                                        x - window->win32.cursorPosX,
                                        y - window->win32.cursorPosY);
            }
            else
                _glfwInputCursorMotion(window, x, y);

            window->win32.cursorPosX = x;
            window->win32.cursorPosY = y;

            if (!window->win32.cursorInside)
            {
                TRACKMOUSEEVENT tme;
                ZeroMemory(&tme, sizeof(tme));
                tme.cbSize = sizeof(tme);
                tme.dwFlags = TME_LEAVE;
                tme.hwndTrack = window->win32.handle;
                TrackMouseEvent(&tme);

                window->win32.cursorInside = GL_TRUE;
                _glfwInputCursorEnter(window, GL_TRUE);
            }

            return 0;
        }

        case WM_MOUSELEAVE:
        {
            window->win32.cursorInside = GL_FALSE;
            _glfwInputCursorEnter(window, GL_FALSE);
            return 0;
        }

        case WM_MOUSEWHEEL:
        {
            _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
            return 0;
        }

        case WM_MOUSEHWHEEL:
        {
            // This message is only sent on Windows Vista and later
            // NOTE: The X-axis is inverted for consistency with OS X and X11.
            _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
            return 0;
        }

        case WM_SIZE:
        {
            if (_glfw.focusedWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
            {
                window->win32.iconified = GL_TRUE;
                _glfwInputWindowIconify(window, GL_TRUE);
            }
            else if (window->win32.iconified &&
                     (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
            {
                window->win32.iconified = GL_FALSE;
                _glfwInputWindowIconify(window, GL_FALSE);
            }

            _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
            _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
            return 0;
        }

        case WM_MOVE:
        {
            if (_glfw.focusedWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
            // those macros do not handle negative window positions correctly
            _glfwInputWindowPos(window,
                                GET_X_LPARAM(lParam),
                                GET_Y_LPARAM(lParam));
            return 0;
        }

        case WM_PAINT:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case WM_ERASEBKGND:
        {
            return TRUE;
        }

        case WM_SETCURSOR:
        {
            if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT)
            {
                if (window->cursorMode == GLFW_CURSOR_HIDDEN ||
                    window->cursorMode == GLFW_CURSOR_DISABLED)
                {
                    SetCursor(NULL);
                    return TRUE;
                }
                else if (window->cursor)
                {
                    SetCursor(window->cursor->win32.handle);
                    return TRUE;
                }
            }

            break;
        }

        case WM_DEVICECHANGE:
        {
            if (DBT_DEVNODES_CHANGED == wParam)
            {
                _glfwInputMonitorChange();
                return TRUE;
            }
            break;
        }

        case WM_DWMCOMPOSITIONCHANGED:
        {
            if (_glfwIsCompositionEnabled())
            {
                _GLFWwindow* previous = _glfwPlatformGetCurrentContext();
                _glfwPlatformMakeContextCurrent(window);
                _glfwPlatformSwapInterval(0);
                _glfwPlatformMakeContextCurrent(previous);
            }

            // TODO: Restore vsync if compositing was disabled
            break;
        }

        case WM_DROPFILES:
        {
            HDROP hDrop = (HDROP) wParam;
            POINT pt;
            int i;

            const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0);
            char** paths = calloc(count, sizeof(char*));

            // Move the mouse to the position of the drop
            DragQueryPoint(hDrop, &pt);
            _glfwInputCursorMotion(window, pt.x, pt.y);

            for (i = 0;  i < count;  i++)
            {
                const UINT length = DragQueryFileW(hDrop, i, NULL, 0);
                WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));

                DragQueryFileW(hDrop, i, buffer, length + 1);
                paths[i] = _glfwCreateUTF8FromWideString(buffer);

                free(buffer);
            }

            _glfwInputDrop(window, count, (const char**) paths);

            for (i = 0;  i < count;  i++)
                free(paths[i]);
            free(paths);

            DragFinish(hDrop);
            return 0;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Esempio n. 12
0
static void processEvent(XEvent *event)
{
    _GLFWwindow* window;

    switch (event->type)
    {
	case KeyPress:
	{
	    // A keyboard key was pressed
	    window = findWindow(event->xkey.window);
	    if (window == NULL)
		return;

	    _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_PRESS);
	    _glfwInputChar(window, translateChar(&event->xkey));
	    break;
	}

	case KeyRelease:
	{
	    // A keyboard key was released
	    window = findWindow(event->xkey.window);
	    if (window == NULL)
		return;

	    // Do not report key releases for key repeats. For key repeats we
	    // will get KeyRelease/KeyPress pairs with similar or identical
	    // time stamps. User selected key repeat filtering is handled in
	    // _glfwInputKey/_glfwInputChar.
	    if (XEventsQueued(_glfwLibrary.X11.display, QueuedAfterReading))
	    {
		XEvent nextEvent;
		XPeekEvent(_glfwLibrary.X11.display, &nextEvent);

		if (nextEvent.type == KeyPress &&
		    nextEvent.xkey.window == event->xkey.window &&
		    nextEvent.xkey.keycode == event->xkey.keycode)
		{
		    // This last check is a hack to work around key repeats
		    // leaking through due to some sort of time drift
		    // Toshiyuki Takahashi can press a button 16 times per
		    // second so it's fairly safe to assume that no human is
		    // pressing the key 50 times per second (value is ms)
		    if ((nextEvent.xkey.time - event->xkey.time) < 20)
		    {
			// Do not report anything for this event
			break;
		    }
		}
	    }

	    _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_RELEASE);
	    break;
	}

	case ButtonPress:
	{
	    // A mouse button was pressed or a scrolling event occurred
	    window = findWindow(event->xbutton.window);
	    if (window == NULL)
		return;

	    if (event->xbutton.button == Button1)
		_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
	    else if (event->xbutton.button == Button2)
		_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS);
	    else if (event->xbutton.button == Button3)
		_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);

	    // XFree86 3.3.2 and later translates mouse wheel up/down into
	    // mouse button 4 & 5 presses
	    else if (event->xbutton.button == Button4)
		_glfwInputScroll(window, 0.0, 1.0);
	    else if (event->xbutton.button == Button5)
		_glfwInputScroll(window, 0.0, -1.0);

	    else if (event->xbutton.button == Button6)
		_glfwInputScroll(window, -1.0, 0.0);
	    else if (event->xbutton.button == Button7)
		_glfwInputScroll(window, 1.0, 0.0);

	    break;
	}

	case ButtonRelease:
	{
	    // A mouse button was released
	    window = findWindow(event->xbutton.window);
	    if (window == NULL)
		return;

	    if (event->xbutton.button == Button1)
	    {
		_glfwInputMouseClick(window,
				     GLFW_MOUSE_BUTTON_LEFT,
				     GLFW_RELEASE);
	    }
	    else if (event->xbutton.button == Button2)
	    {
		_glfwInputMouseClick(window,
				     GLFW_MOUSE_BUTTON_MIDDLE,
				     GLFW_RELEASE);
	    }
	    else if (event->xbutton.button == Button3)
	    {
		_glfwInputMouseClick(window,
				     GLFW_MOUSE_BUTTON_RIGHT,
				     GLFW_RELEASE);
	    }
	    break;
	}

	case EnterNotify:
	{
	    // The cursor entered the window
	    window = findWindow(event->xcrossing.window);
	    if (window == NULL)
		return;

	    if (window->cursorMode == GLFW_CURSOR_HIDDEN)
		hideCursor(window);

	    _glfwInputCursorEnter(window, GL_TRUE);
	    break;
	}

	case LeaveNotify:
	{
	    // The cursor left the window
	    window = findWindow(event->xcrossing.window);
	    if (window == NULL)
		return;

	    if (window->cursorMode == GLFW_CURSOR_HIDDEN)
		showCursor(window);

	    _glfwInputCursorEnter(window, GL_FALSE);
	    break;
	}

	case MotionNotify:
	{
	    // The cursor was moved
	    window = findWindow(event->xmotion.window);
	    if (window == NULL)
		return;

	    if (event->xmotion.x != window->X11.cursorPosX ||
		event->xmotion.y != window->X11.cursorPosY)
	    {
		// The cursor was moved by something other than GLFW

		int x, y;

		if (window->cursorMode == GLFW_CURSOR_CAPTURED)
		{
		    if (_glfwLibrary.activeWindow != window)
			break;

		    x = event->xmotion.x - window->X11.cursorPosX;
		    y = event->xmotion.y - window->X11.cursorPosY;
		}
		else
		{
		    x = event->xmotion.x;
		    y = event->xmotion.y;
		}

		window->X11.cursorPosX = event->xmotion.x;
		window->X11.cursorPosY = event->xmotion.y;
		window->X11.cursorCentered = GL_FALSE;

		_glfwInputCursorMotion(window, x, y);
	    }

	    break;
	}

	case ConfigureNotify:
	{
	    // The window configuration changed somehow
	    window = findWindow(event->xconfigure.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowSize(window,
				 event->xconfigure.width,
				 event->xconfigure.height);

	    _glfwInputWindowPos(window,
				event->xconfigure.x,
				event->xconfigure.y);

	    break;
	}

	case ClientMessage:
	{
	    // Custom client message, probably from the window manager
	    window = findWindow(event->xclient.window);
	    if (window == NULL)
		return;

	    if ((Atom) event->xclient.data.l[0] == _glfwLibrary.X11.wmDeleteWindow)
	    {
		// The window manager was asked to close the window, for example by
		// the user pressing a 'close' window decoration button

		_glfwInputWindowCloseRequest(window);
	    }
	    else if (_glfwLibrary.X11.wmPing != None &&
		     (Atom) event->xclient.data.l[0] == _glfwLibrary.X11.wmPing)
	    {
		// The window manager is pinging the application to ensure it's
		// still responding to events

		event->xclient.window = _glfwLibrary.X11.root;
		XSendEvent(_glfwLibrary.X11.display,
			   event->xclient.window,
			   False,
			   SubstructureNotifyMask | SubstructureRedirectMask,
			   event);
	    }

	    break;
	}

	case MapNotify:
	{
	    // The window was mapped
	    window = findWindow(event->xmap.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowVisibility(window, GL_TRUE);
	    _glfwInputWindowIconify(window, GL_FALSE);
	    break;
	}

	case UnmapNotify:
	{
	    // The window was unmapped
	    window = findWindow(event->xmap.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowVisibility(window, GL_FALSE);
	    _glfwInputWindowIconify(window, GL_TRUE);
	    break;
	}

	case FocusIn:
	{
	    // The window gained focus
	    window = findWindow(event->xfocus.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowFocus(window, GL_TRUE);

	    if (window->cursorMode == GLFW_CURSOR_CAPTURED)
		captureCursor(window);

	    break;
	}

	case FocusOut:
	{
	    // The window lost focus
	    window = findWindow(event->xfocus.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowFocus(window, GL_FALSE);

	    if (window->cursorMode == GLFW_CURSOR_CAPTURED)
		showCursor(window);

	    break;
	}

	case Expose:
	{
	    // The window's contents was damaged
	    window = findWindow(event->xexpose.window);
	    if (window == NULL)
		return;

	    _glfwInputWindowDamage(window);
	    break;
	}

	case SelectionClear:
	{
	    // The ownership of the selection was lost

	    free(_glfwLibrary.X11.selection.string);
	    _glfwLibrary.X11.selection.string = NULL;
	    break;
	}

	case SelectionNotify:
	{
	    // The selection conversion status is available

	    XSelectionEvent* request = &event->xselection;

	    if (_glfwReadSelection(request))
		_glfwLibrary.X11.selection.status = _GLFW_CONVERSION_SUCCEEDED;
	    else
		_glfwLibrary.X11.selection.status = _GLFW_CONVERSION_FAILED;

	    break;
	}

	case SelectionRequest:
	{
	    // The contents of the selection was requested

	    XSelectionRequestEvent* request = &event->xselectionrequest;

	    XEvent response;
	    memset(&response, 0, sizeof(response));

	    response.xselection.property = _glfwWriteSelection(request);
	    response.xselection.type = SelectionNotify;
	    response.xselection.display = request->display;
	    response.xselection.requestor = request->requestor;
	    response.xselection.selection = request->selection;
	    response.xselection.target = request->target;
	    response.xselection.time = request->time;

	    XSendEvent(_glfwLibrary.X11.display,
		       request->requestor,
		       False, 0, &response);
	    break;
	}

	case DestroyNotify:
	    return;

	default:
	{
#if defined(_GLFW_HAS_XRANDR)
	    switch (event->type - _glfwLibrary.X11.RandR.eventBase)
	    {
		case RRScreenChangeNotify:
		{
		    XRRUpdateConfiguration(event);
		    break;
		}
	    }
#endif /*_GLFW_HAS_XRANDR*/
	    break;
	}
    }
}
Esempio n. 13
0
// Process the specified X event
//
static void processEvent(XEvent *event)
{
    _GLFWwindow* window = NULL;

    if (event->type != GenericEvent)
    {
        window = _glfwFindWindowByHandle(event->xany.window);
        if (window == NULL)
        {
            // This is either an event for a destroyed GLFW window or an event
            // of a type not currently supported by GLFW
            return;
        }
    }

    switch (event->type)
    {
        case KeyPress:
        {
            _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_PRESS);

            if (!(event->xkey.state & ControlMask) &&
                !(event->xkey.state & Mod1Mask /*Alt*/))
            {
            _glfwInputChar(window, translateChar(&event->xkey));
            }

            break;
        }

        case KeyRelease:
        {
            _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_RELEASE);
            break;
        }

        case ButtonPress:
        {
            if (event->xbutton.button == Button1)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
            else if (event->xbutton.button == Button2)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS);
            else if (event->xbutton.button == Button3)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);

            // Modern X provides scroll events as mouse button presses
            else if (event->xbutton.button == Button4)
                _glfwInputScroll(window, 0.0, 1.0);
            else if (event->xbutton.button == Button5)
                _glfwInputScroll(window, 0.0, -1.0);
            else if (event->xbutton.button == Button6)
                _glfwInputScroll(window, -1.0, 0.0);
            else if (event->xbutton.button == Button7)
                _glfwInputScroll(window, 1.0, 0.0);

            break;
        }

        case ButtonRelease:
        {
            if (event->xbutton.button == Button1)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_LEFT,
                                     GLFW_RELEASE);
            }
            else if (event->xbutton.button == Button2)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_MIDDLE,
                                     GLFW_RELEASE);
            }
            else if (event->xbutton.button == Button3)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_RIGHT,
                                     GLFW_RELEASE);
            }
            break;
        }

        case EnterNotify:
        {
            if (window->cursorMode == GLFW_CURSOR_HIDDEN)
                hideCursor(window);

            _glfwInputCursorEnter(window, GL_TRUE);
            break;
        }

        case LeaveNotify:
        {
            if (window->cursorMode == GLFW_CURSOR_HIDDEN)
                showCursor(window);

            _glfwInputCursorEnter(window, GL_FALSE);
            break;
        }

        case MotionNotify:
        {
            if (event->xmotion.x != window->x11.cursorPosX ||
                event->xmotion.y != window->x11.cursorPosY)
            {
                // The cursor was moved by something other than GLFW

                int x, y;

                if (window->cursorMode == GLFW_CURSOR_CAPTURED)
                {
                    if (_glfw.focusedWindow != window)
                        break;

                    x = event->xmotion.x - window->x11.cursorPosX;
                    y = event->xmotion.y - window->x11.cursorPosY;
                }
                else
                {
                    x = event->xmotion.x;
                    y = event->xmotion.y;
                }

                window->x11.cursorPosX = event->xmotion.x;
                window->x11.cursorPosY = event->xmotion.y;
                window->x11.cursorCentered = GL_FALSE;

                _glfwInputCursorMotion(window, x, y);
            }

            break;
        }

        case ConfigureNotify:
        {
            _glfwInputWindowSize(window,
                                 event->xconfigure.width,
                                 event->xconfigure.height);

            _glfwInputWindowPos(window,
                                event->xconfigure.x,
                                event->xconfigure.y);

            break;
        }

        case ClientMessage:
        {
            // Custom client message, probably from the window manager

            if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW)
            {
                // The window manager was asked to close the window, for example by
                // the user pressing a 'close' window decoration button

                _glfwInputWindowCloseRequest(window);
            }
            else if (_glfw.x11.NET_WM_PING != None &&
                     (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING)
            {
                // The window manager is pinging the application to ensure it's
                // still responding to events

                event->xclient.window = _glfw.x11.root;
                XSendEvent(_glfw.x11.display,
                           event->xclient.window,
                           False,
                           SubstructureNotifyMask | SubstructureRedirectMask,
                           event);
            }

            break;
        }

        case MapNotify:
        {
            _glfwInputWindowVisibility(window, GL_TRUE);
            break;
        }

        case UnmapNotify:
        {
            _glfwInputWindowVisibility(window, GL_FALSE);
            break;
        }

        case FocusIn:
        {
            _glfwInputWindowFocus(window, GL_TRUE);

            if (window->cursorMode == GLFW_CURSOR_CAPTURED)
                captureCursor(window);

            break;
        }

        case FocusOut:
        {
            _glfwInputWindowFocus(window, GL_FALSE);

            if (window->cursorMode == GLFW_CURSOR_CAPTURED)
                showCursor(window);

            break;
        }

        case Expose:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case PropertyNotify:
        {
            if (event->xproperty.atom == _glfw.x11.WM_STATE &&
                event->xproperty.state == PropertyNewValue)
            {
                struct {
                    CARD32 state;
                    Window icon;
                } *state = NULL;

                if (_glfwGetWindowProperty(window->x11.handle,
                                           _glfw.x11.WM_STATE,
                                           _glfw.x11.WM_STATE,
                                           (unsigned char**) &state) >= 2)
                {
                    if (state->state == IconicState)
                        _glfwInputWindowIconify(window, GL_TRUE);
                    else if (state->state == NormalState)
                        _glfwInputWindowIconify(window, GL_FALSE);
                }

                XFree(state);
            }

            break;
        }

        case SelectionClear:
        {
            // The ownership of the clipboard selection was lost

            free(_glfw.x11.selection.string);
            _glfw.x11.selection.string = NULL;
            break;
        }

        case SelectionRequest:
        {
            // The contents of the clipboard selection was requested

            XSelectionRequestEvent* request = &event->xselectionrequest;

            XEvent response;
            memset(&response, 0, sizeof(response));

            response.xselection.property = _glfwWriteSelection(request);
            response.xselection.type = SelectionNotify;
            response.xselection.display = request->display;
            response.xselection.requestor = request->requestor;
            response.xselection.selection = request->selection;
            response.xselection.target = request->target;
            response.xselection.time = request->time;

            XSendEvent(_glfw.x11.display,
                       request->requestor,
                       False, 0, &response);
            break;
        }

        case DestroyNotify:
            return;

        case GenericEvent:
        {
            if (event->xcookie.extension == _glfw.x11.xi2.majorOpcode &&
                XGetEventData(_glfw.x11.display, &event->xcookie))
            {
                if (event->xcookie.evtype == XI_Motion)
                {
                    XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data;

                    window = _glfwFindWindowByHandle(data->event);
                    if (window)
                    {
                        if (data->event_x != window->x11.cursorPosX ||
                            data->event_y != window->x11.cursorPosY)
                        {
                            // The cursor was moved by something other than GLFW

                            double x, y;

                            if (window->cursorMode == GLFW_CURSOR_CAPTURED)
                            {
                                if (_glfw.focusedWindow != window)
                                    break;

                                x = data->event_x - window->x11.cursorPosX;
                                y = data->event_y - window->x11.cursorPosY;
                            }
                            else
                            {
                                x = data->event_x;
                                y = data->event_y;
                            }

                            window->x11.cursorPosX = data->event_x;
                            window->x11.cursorPosY = data->event_y;
                            window->x11.cursorCentered = GL_FALSE;

                            _glfwInputCursorMotion(window, x, y);
                        }
                    }
                }
            }

            XFreeEventData(_glfw.x11.display, &event->xcookie);
            break;
        }

        default:
        {
            switch (event->type - _glfw.x11.randr.eventBase)
            {
                case RRScreenChangeNotify:
                {
                    XRRUpdateConfiguration(event);
                    break;
                }
            }

            break;
        }
    }
}
Esempio n. 14
0
int32_t _glfwPlatformProcInputEvent( struct android_app* app, AInputEvent *event )
{
    // Motion events
    if ( AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION ) {
        int action = AKeyEvent_getAction(event);
        int count = AMotionEvent_getPointerCount(event);
        switch (action & AMOTION_EVENT_ACTION_MASK) {
            case AMOTION_EVENT_ACTION_DOWN:
                if(count == 1){
                   _glfwInput.MousePosX = AMotionEvent_getX(event, 0);
                   _glfwInput.MousePosY = AMotionEvent_getY(event, 0);
                   if(_glfwWin.mousePosCallback)
                      _glfwWin.mousePosCallback(_glfwInput.MousePosX, _glfwInput.MousePosY, GLFW_RELEASE, GLFW_RELEASE);
                  _glfwInputMouseClick(GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
                }
                break;
            case AMOTION_EVENT_ACTION_UP:
                if(count == 1){
                   _glfwInput.MousePosX = AMotionEvent_getX(event, 0);
                   _glfwInput.MousePosY = AMotionEvent_getY(event, 0);
                   if(_glfwWin.mousePosCallback)
                      _glfwWin.mousePosCallback(_glfwInput.MousePosX, _glfwInput.MousePosY, GLFW_RELEASE, GLFW_RELEASE);
                  _glfwInputMouseClick(GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE);
                }
                break;
            case AMOTION_EVENT_ACTION_MOVE:
                if(count == 1){
                   _glfwInput.MousePosX = AMotionEvent_getX(event, 0);
                   _glfwInput.MousePosY = AMotionEvent_getY(event, 0);
                   if(_glfwWin.mousePosCallback)
                      _glfwWin.mousePosCallback(_glfwInput.MousePosX, _glfwInput.MousePosY, GLFW_RELEASE, GLFW_RELEASE);
                }else if(count == 2){
                    int old_x1 = (int) _glfwInput.MousePosX;
                    int old_y1 = (int) _glfwInput.MousePosY;
                    int old_x2 = (int) _glfwInput.MousePosX2;
                    int old_y2 = (int) _glfwInput.MousePosY2;
                    int new_x1 = (int) AMotionEvent_getX(event, 0);
                    int new_y1 = (int) AMotionEvent_getY(event, 0);
                    int new_x2 = (int) AMotionEvent_getX(event, 1);
                    int new_y2 = (int) AMotionEvent_getY(event, 1);
                    if(old_x1 == new_x1 && old_y1 == new_y1) {
                    } else if(old_x2 == new_x2 && old_y2 == new_y2) {
                    } else {
                        if(abs((new_x2 - new_x1) * (new_y2 - new_y1)) > abs((old_x2 - old_x1) * (old_y2 - old_y1))){
                            _glfwInput.WheelPos++;
                        }else{
                            _glfwInput.WheelPos--;
                        }
                        if(_glfwWin.mouseWheelCallback)
                             _glfwWin.mouseWheelCallback(_glfwInput.WheelPos);
                    }
                }
                _glfwInput.MousePosX  = AMotionEvent_getX(event, 0);
                _glfwInput.MousePosY  = AMotionEvent_getY(event, 0);
                _glfwInput.MousePosX2 = AMotionEvent_getX(event, 1);
                _glfwInput.MousePosY2 = AMotionEvent_getY(event, 1);
                break;
        }
        return 1;
    }
    return 0;
}
Esempio n. 15
0
OSStatus _glfwMouseEventHandler( EventHandlerCallRef handlerCallRef,
                                 EventRef event,
                                 void *userData )
{
    switch( GetEventKind( event ) )
    {
        case kEventMouseDown:
        {
            WindowRef window;
            EventRecord oldStyleMacEvent;
            ConvertEventRefToEventRecord( event, &oldStyleMacEvent );
            if( FindWindow ( oldStyleMacEvent.where, &window ) == inMenuBar )
            {
                MenuSelect( oldStyleMacEvent.where );
                HiliteMenu(0);
                return noErr;
            }
            else
            {
                EventMouseButton button;
                if( GetEventParameter( event,
                                       kEventParamMouseButton,
                                       typeMouseButton,
                                       NULL,
                                       sizeof( EventMouseButton ),
                                       NULL,
                                       &button ) == noErr )
                {
                    button -= kEventMouseButtonPrimary;
                    if( button <= GLFW_MOUSE_BUTTON_LAST )
                    {
                        _glfwInputMouseClick( button
                                              + GLFW_MOUSE_BUTTON_LEFT,
                                              GLFW_PRESS );
                    }
                    return noErr;
                }
            }
            break;
        }

        case kEventMouseUp:
        {
            EventMouseButton button;
            if( GetEventParameter( event,
                                   kEventParamMouseButton,
                                   typeMouseButton,
                                   NULL,
                                   sizeof( EventMouseButton ),
                                   NULL,
                                   &button ) == noErr )
            {
                button -= kEventMouseButtonPrimary;
                if( button <= GLFW_MOUSE_BUTTON_LAST )
                {
                    _glfwInputMouseClick( button
                                          + GLFW_MOUSE_BUTTON_LEFT,
                                          GLFW_RELEASE );
                }
                return noErr;
            }
            break;
        }

        case kEventMouseMoved:
        case kEventMouseDragged:
        {
            HIPoint mouseLocation;
	    if( _glfwWin.MouseLock )
	    {
		if( GetEventParameter( event,
				       kEventParamMouseDelta,
				       typeHIPoint,
				       NULL,
				       sizeof( HIPoint ),
				       NULL,
				       &mouseLocation ) != noErr )
		{
		    break;
		}

		_glfwInput.MousePosX += mouseLocation.x;
		_glfwInput.MousePosY += mouseLocation.y;
	    }
	    else
	    {
		if( GetEventParameter( event,
				       kEventParamMouseLocation,
				       typeHIPoint,
				       NULL,
				       sizeof( HIPoint ),
				       NULL,
				       &mouseLocation ) != noErr )
		{
		    break;
		}

		_glfwInput.MousePosX = mouseLocation.x;
		_glfwInput.MousePosY = mouseLocation.y;

		if( !_glfwWin.Fullscreen )
		{
		    Rect content;
		    GetWindowBounds( _glfwWin.MacWindow,
		                     kWindowContentRgn,
				     &content );

		    _glfwInput.MousePosX -= content.left;
		    _glfwInput.MousePosY -= content.top;
		}
	    }

	    if( _glfwWin.MousePosCallback )
	    {
		_glfwWin.MousePosCallback( _glfwInput.MousePosX,
					   _glfwInput.MousePosY );
	    }

            break;
        }

        case kEventMouseWheelMoved:
        {
            EventMouseWheelAxis axis;
            if( GetEventParameter( event,
                                   kEventParamMouseWheelAxis,
                                   typeMouseWheelAxis,
                                   NULL,
                                   sizeof( EventMouseWheelAxis ),
                                   NULL,
                                   &axis) == noErr )
            {
                long wheelDelta;
                if( axis == kEventMouseWheelAxisY &&
                    GetEventParameter( event,
                                       kEventParamMouseWheelDelta,
                                       typeLongInteger,
                                       NULL,
                                       sizeof( long ),
                                       NULL,
                                       &wheelDelta ) == noErr )
                {
                    _glfwInput.WheelPos += wheelDelta;
                    if( _glfwWin.MouseWheelCallback )
                    {
                        _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
                    }
                    return noErr;
                }
            }
            break;
        }
    }

    return eventNotHandledErr;
}
Esempio n. 16
0
// Process the specified X event
//
static void processEvent(XEvent *event)
{
    _GLFWwindow* window = NULL;

    if (event->type != GenericEvent)
    {
        window = _glfwFindWindowByHandle(event->xany.window);
        if (window == NULL)
        {
            // This is an event for a window that has already been destroyed
            return;
        }
    }

    switch (event->type)
    {
        case KeyPress:
        {
            const int key = translateKey(event->xkey.keycode);
            const int mods = translateState(event->xkey.state);
            const int character = translateChar(&event->xkey);

            _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods);

            if (character != -1)
                _glfwInputChar(window, character);

            break;
        }

        case KeyRelease:
        {
            const int key = translateKey(event->xkey.keycode);
            const int mods = translateState(event->xkey.state);

            _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods);
            break;
        }

        case ButtonPress:
        {
            const int mods = translateState(event->xbutton.state);

            if (event->xbutton.button == Button1)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
            else if (event->xbutton.button == Button2)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
            else if (event->xbutton.button == Button3)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);

            // Modern X provides scroll events as mouse button presses
            else if (event->xbutton.button == Button4)
                _glfwInputScroll(window, 0.0, 1.0);
            else if (event->xbutton.button == Button5)
                _glfwInputScroll(window, 0.0, -1.0);
            else if (event->xbutton.button == Button6)
                _glfwInputScroll(window, -1.0, 0.0);
            else if (event->xbutton.button == Button7)
                _glfwInputScroll(window, 1.0, 0.0);

            else
            {
                // Additional buttons after 7 are treated as regular buttons
                // We subtract 4 to fill the gap left by scroll input above
                _glfwInputMouseClick(window,
                                     event->xbutton.button - 4,
                                     GLFW_PRESS,
                                     mods);
            }

            break;
        }

        case ButtonRelease:
        {
            const int mods = translateState(event->xbutton.state);

            if (event->xbutton.button == Button1)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_LEFT,
                                     GLFW_RELEASE,
                                     mods);
            }
            else if (event->xbutton.button == Button2)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_MIDDLE,
                                     GLFW_RELEASE,
                                     mods);
            }
            else if (event->xbutton.button == Button3)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_RIGHT,
                                     GLFW_RELEASE,
                                     mods);
            }
            else if (event->xbutton.button > Button7)
            {
                // Additional buttons after 7 are treated as regular buttons
                // We subtract 4 to fill the gap left by scroll input above
                _glfwInputMouseClick(window,
                                     event->xbutton.button - 4,
                                     GLFW_RELEASE,
                                     mods);
            }
            break;
        }

        case EnterNotify:
        {
            _glfwInputCursorEnter(window, GL_TRUE);
            break;
        }

        case LeaveNotify:
        {
            _glfwInputCursorEnter(window, GL_FALSE);
            break;
        }

        case MotionNotify:
        {
            if (event->xmotion.x != window->x11.warpPosX ||
                event->xmotion.y != window->x11.warpPosY)
            {
                // The cursor was moved by something other than GLFW

                int x, y;

                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                {
                    if (_glfw.focusedWindow != window)
                        break;

                    x = event->xmotion.x - window->x11.cursorPosX;
                    y = event->xmotion.y - window->x11.cursorPosY;
                }
                else
                {
                    x = event->xmotion.x;
                    y = event->xmotion.y;
                }

                _glfwInputCursorMotion(window, x, y);
            }

            window->x11.cursorPosX = event->xmotion.x;
            window->x11.cursorPosY = event->xmotion.y;
            break;
        }

        case ConfigureNotify:
        {
            if (event->xconfigure.width != window->x11.width ||
                event->xconfigure.height != window->x11.height)
            {
                _glfwInputFramebufferSize(window,
                                          event->xconfigure.width,
                                          event->xconfigure.height);

                _glfwInputWindowSize(window,
                                     event->xconfigure.width,
                                     event->xconfigure.height);

                window->x11.width = event->xconfigure.width;
                window->x11.height = event->xconfigure.height;
            }

            if (event->xconfigure.x != window->x11.xpos ||
                event->xconfigure.y != window->x11.ypos)
            {
                _glfwInputWindowPos(window,
                                    event->xconfigure.x,
                                    event->xconfigure.y);

                window->x11.xpos = event->xconfigure.x;
                window->x11.ypos = event->xconfigure.y;
            }

            break;
        }

        case ClientMessage:
        {
            // Custom client message, probably from the window manager

            if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW)
            {
                // The window manager was asked to close the window, for example by
                // the user pressing a 'close' window decoration button

                _glfwInputWindowCloseRequest(window);
            }
            else if (_glfw.x11.NET_WM_PING &&
                     (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING)
            {
                // The window manager is pinging the application to ensure it's
                // still responding to events

                event->xclient.window = _glfw.x11.root;
                XSendEvent(_glfw.x11.display,
                           event->xclient.window,
                           False,
                           SubstructureNotifyMask | SubstructureRedirectMask,
                           event);
            }
            else if (event->xclient.message_type == _glfw.x11.XdndEnter)
            {
                // A drag operation has entered the window
                // TODO: Check if UTF-8 string is supported by the source
            }
            else if (event->xclient.message_type == _glfw.x11.XdndDrop)
            {
                // The drag operation has finished dropping on
                // the window, ask to convert it to a UTF-8 string
                _glfw.x11.xdnd.source = event->xclient.data.l[0];
                XConvertSelection(_glfw.x11.display,
                                  _glfw.x11.XdndSelection,
                                  _glfw.x11.UTF8_STRING,
                                  _glfw.x11.XdndSelection,
                                  window->x11.handle, CurrentTime);
            }
            else if (event->xclient.message_type == _glfw.x11.XdndPosition)
            {
                // The drag operation has moved over the window
                const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;
                const int absY = (event->xclient.data.l[2]) & 0xFFFF;
                int x, y;

                _glfwPlatformGetWindowPos(window, &x, &y);
                _glfwInputCursorMotion(window, absX - x, absY - y);

                // Reply that we are ready to copy the dragged data
                XEvent reply;
                memset(&reply, 0, sizeof(reply));

                reply.type = ClientMessage;
                reply.xclient.window = event->xclient.data.l[0];
                reply.xclient.message_type = _glfw.x11.XdndStatus;
                reply.xclient.format = 32;
                reply.xclient.data.l[0] = window->x11.handle;
                reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle
                reply.xclient.data.l[2] = 0; // Specify an empty rectangle
                reply.xclient.data.l[3] = 0;
                reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;

                XSendEvent(_glfw.x11.display, event->xclient.data.l[0],
                           False, NoEventMask, &reply);
                XFlush(_glfw.x11.display);
            }

            break;
        }

        case SelectionNotify:
        {
            if (event->xselection.property)
            {
                // The converted data from the drag operation has arrived
                char* data;
                const int result = _glfwGetWindowProperty(event->xselection.requestor,
                                                          event->xselection.property,
                                                          event->xselection.target,
                                                          (unsigned char**) &data);

                if (result)
                {
                    int i, count;
                    char** names = splitUriList(data, &count);

                    _glfwInputDrop(window, count, (const char**) names);

                    for (i = 0;  i < count;  i++)
                        free(names[i]);
                    free(names);
                }

                XFree(data);

                XEvent reply;
                memset(&reply, 0, sizeof(reply));

                reply.type = ClientMessage;
                reply.xclient.window = _glfw.x11.xdnd.source;
                reply.xclient.message_type = _glfw.x11.XdndFinished;
                reply.xclient.format = 32;
                reply.xclient.data.l[0] = window->x11.handle;
                reply.xclient.data.l[1] = result;
                reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;

                // Reply that all is well
                XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
                           False, NoEventMask, &reply);
                XFlush(_glfw.x11.display);
            }

            break;
        }

        case MapNotify:
        {
            _glfwInputWindowVisibility(window, GL_TRUE);
            break;
        }

        case UnmapNotify:
        {
            _glfwInputWindowVisibility(window, GL_FALSE);
            break;
        }

        case FocusIn:
        {
            _glfwInputWindowFocus(window, GL_TRUE);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                disableCursor(window);

            break;
        }

        case FocusOut:
        {
            _glfwInputWindowFocus(window, GL_FALSE);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                restoreCursor(window);

            break;
        }

        case Expose:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case PropertyNotify:
        {
            if (event->xproperty.atom == _glfw.x11.WM_STATE &&
                event->xproperty.state == PropertyNewValue)
            {
                struct {
                    CARD32 state;
                    Window icon;
                } *state = NULL;

                if (_glfwGetWindowProperty(window->x11.handle,
                                           _glfw.x11.WM_STATE,
                                           _glfw.x11.WM_STATE,
                                           (unsigned char**) &state) >= 2)
                {
                    if (state->state == IconicState)
                        _glfwInputWindowIconify(window, GL_TRUE);
                    else if (state->state == NormalState)
                        _glfwInputWindowIconify(window, GL_FALSE);
                }

                XFree(state);
            }

            break;
        }

        case SelectionClear:
        {
            _glfwHandleSelectionClear(event);
            break;
        }

        case SelectionRequest:
        {
            _glfwHandleSelectionRequest(event);
            break;
        }

        case DestroyNotify:
            return;

        case GenericEvent:
        {
            if (event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
                XGetEventData(_glfw.x11.display, &event->xcookie))
            {
                if (event->xcookie.evtype == XI_Motion)
                {
                    XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data;

                    window = _glfwFindWindowByHandle(data->event);
                    if (window)
                    {
                        if (data->event_x != window->x11.warpPosX ||
                            data->event_y != window->x11.warpPosY)
                        {
                            // The cursor was moved by something other than GLFW

                            double x, y;

                            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                            {
                                if (_glfw.focusedWindow != window)
                                    break;

                                x = data->event_x - window->x11.cursorPosX;
                                y = data->event_y - window->x11.cursorPosY;
                            }
                            else
                            {
                                x = data->event_x;
                                y = data->event_y;
                            }

                            _glfwInputCursorMotion(window, x, y);
                        }

                        window->x11.cursorPosX = data->event_x;
                        window->x11.cursorPosY = data->event_y;
                    }
                }
            }

            XFreeEventData(_glfw.x11.display, &event->xcookie);
            break;
        }

        default:
        {
            switch (event->type - _glfw.x11.randr.eventBase)
            {
                case RRScreenChangeNotify:
                {
                    XRRUpdateConfiguration(event);
                    break;
                }
            }

            break;
        }
    }
}
Esempio n. 17
0
// Process the specified X event
//
static void processEvent(XEvent *event)
{
    _GLFWwindow* window = NULL;

    if (event->type != GenericEvent)
    {
        window = _glfwFindWindowByHandle(event->xany.window);
        if (window == NULL)
        {
            // This is an event for a window that has already been destroyed
            return;
        }
    }

    switch (event->type)
    {
        case KeyPress:
        {
            const int key = translateKey(event->xkey.keycode);
            const int mods = translateState(event->xkey.state);
            const int character = translateChar(&event->xkey);

            _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods);

            if (character != -1)
                _glfwInputChar(window, character);

            break;
        }

        case KeyRelease:
        {
            const int key = translateKey(event->xkey.keycode);
            const int mods = translateState(event->xkey.state);

            _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods);
            break;
        }

        case ButtonPress:
        {
            const int mods = translateState(event->xbutton.state);

            if (event->xbutton.button == Button1)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
            else if (event->xbutton.button == Button2)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
            else if (event->xbutton.button == Button3)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);

            // Modern X provides scroll events as mouse button presses
            else if (event->xbutton.button == Button4)
                _glfwInputScroll(window, 0.0, 1.0);
            else if (event->xbutton.button == Button5)
                _glfwInputScroll(window, 0.0, -1.0);
            else if (event->xbutton.button == Button6)
                _glfwInputScroll(window, -1.0, 0.0);
            else if (event->xbutton.button == Button7)
                _glfwInputScroll(window, 1.0, 0.0);

            break;
        }

        case ButtonRelease:
        {
            const int mods = translateState(event->xbutton.state);

            if (event->xbutton.button == Button1)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_LEFT,
                                     GLFW_RELEASE,
                                     mods);
            }
            else if (event->xbutton.button == Button2)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_MIDDLE,
                                     GLFW_RELEASE,
                                     mods);
            }
            else if (event->xbutton.button == Button3)
            {
                _glfwInputMouseClick(window,
                                     GLFW_MOUSE_BUTTON_RIGHT,
                                     GLFW_RELEASE,
                                     mods);
            }
            break;
        }

        case EnterNotify:
        {
            if (window->cursorMode == GLFW_CURSOR_HIDDEN)
                hideCursor(window);

            _glfwInputCursorEnter(window, GL_TRUE);
            break;
        }

        case LeaveNotify:
        {
            if (window->cursorMode == GLFW_CURSOR_HIDDEN)
                showCursor(window);

            _glfwInputCursorEnter(window, GL_FALSE);
            break;
        }

        case MotionNotify:
        {
            if (event->xmotion.x != window->x11.warpPosX ||
                event->xmotion.y != window->x11.warpPosY)
            {
                // The cursor was moved by something other than GLFW

                int x, y;

                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                {
                    if (_glfw.focusedWindow != window)
                        break;

                    x = event->xmotion.x - window->x11.cursorPosX;
                    y = event->xmotion.y - window->x11.cursorPosY;
                }
                else
                {
                    x = event->xmotion.x;
                    y = event->xmotion.y;
                }

                _glfwInputCursorMotion(window, x, y);
            }

            window->x11.cursorPosX = event->xmotion.x;
            window->x11.cursorPosY = event->xmotion.y;
            break;
        }

        case ConfigureNotify:
        {
            if (event->xconfigure.width != window->x11.width ||
                event->xconfigure.height != window->x11.height)
            {
                _glfwInputFramebufferSize(window,
                                          event->xconfigure.width,
                                          event->xconfigure.height);

                _glfwInputWindowSize(window,
                                     event->xconfigure.width,
                                     event->xconfigure.height);

                window->x11.width = event->xconfigure.width;
                window->x11.height = event->xconfigure.height;
            }

            if (event->xconfigure.x != window->x11.xpos ||
                event->xconfigure.y != window->x11.ypos)
            {
                _glfwInputWindowPos(window,
                                    event->xconfigure.x,
                                    event->xconfigure.y);

                window->x11.xpos = event->xconfigure.x;
                window->x11.ypos = event->xconfigure.y;
            }

            break;
        }

        case ClientMessage:
        {
            // Custom client message, probably from the window manager

            if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW)
            {
                // The window manager was asked to close the window, for example by
                // the user pressing a 'close' window decoration button

                _glfwInputWindowCloseRequest(window);
            }
            else if (_glfw.x11.NET_WM_PING != None &&
                     (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING)
            {
                // The window manager is pinging the application to ensure it's
                // still responding to events

                event->xclient.window = _glfw.x11.root;
                XSendEvent(_glfw.x11.display,
                           event->xclient.window,
                           False,
                           SubstructureNotifyMask | SubstructureRedirectMask,
                           event);
            }

            break;
        }

        case MapNotify:
        {
            _glfwInputWindowVisibility(window, GL_TRUE);
            break;
        }

        case UnmapNotify:
        {
            _glfwInputWindowVisibility(window, GL_FALSE);
            break;
        }

        case FocusIn:
        {
            _glfwInputWindowFocus(window, GL_TRUE);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                captureCursor(window);

            break;
        }

        case FocusOut:
        {
            _glfwInputWindowFocus(window, GL_FALSE);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                showCursor(window);

            break;
        }

        case Expose:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case PropertyNotify:
        {
            if (event->xproperty.atom == _glfw.x11.WM_STATE &&
                event->xproperty.state == PropertyNewValue)
            {
                struct {
                    CARD32 state;
                    Window icon;
                } *state = NULL;

                if (_glfwGetWindowProperty(window->x11.handle,
                                           _glfw.x11.WM_STATE,
                                           _glfw.x11.WM_STATE,
                                           (unsigned char**) &state) >= 2)
                {
                    if (state->state == IconicState)
                        _glfwInputWindowIconify(window, GL_TRUE);
                    else if (state->state == NormalState)
                        _glfwInputWindowIconify(window, GL_FALSE);
                }

                XFree(state);
            }

            break;
        }

        case SelectionClear:
        {
            _glfwHandleSelectionClear(event);
            break;
        }

        case SelectionRequest:
        {
            _glfwHandleSelectionRequest(event);
            break;
        }

        case DestroyNotify:
            return;

        case GenericEvent:
        {
            if (event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
                XGetEventData(_glfw.x11.display, &event->xcookie))
            {
/*              if (event->xcookie.evtype == XI_Motion)
                {
                    XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data;

                    window = _glfwFindWindowByHandle(data->event);
                    if (window)
                    {
                        if (data->event_x != window->x11.warpPosX ||
                            data->event_y != window->x11.warpPosY)
                        {
                            // The cursor was moved by something other than GLFW

                            double x, y;

                            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                            {
                                if (_glfw.focusedWindow != window)
                                    break;

                                x = data->event_x - window->x11.cursorPosX;
                                y = data->event_y - window->x11.cursorPosY;
                            }
                            else
                            {
                                x = data->event_x;
                                y = data->event_y;
                            }

                            _glfwInputCursorMotion(window, x, y);
                        }

                        window->x11.cursorPosX = data->event_x;
                        window->x11.cursorPosY = data->event_y;
                    }
                }*/
            }

            XFreeEventData(_glfw.x11.display, &event->xcookie);
            break;
        }

        default:
        {
/*          switch (event->type - _glfw.x11.randr.eventBase)
            {
                case RRScreenChangeNotify:
                {
                    XRRUpdateConfiguration(event);
                    break;
                }
            }
*/
            break;
        }
    }
}
Esempio n. 18
0
static void pointerHandleButton(void* data,
                                struct wl_pointer* pointer,
                                uint32_t serial,
                                uint32_t time,
                                uint32_t button,
                                uint32_t state)
{
    _GLFWwindow* window = _glfw.wl.pointerFocus;
    int glfwButton;

    // Both xdg-shell and wl_shell use the same values.
    uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE;

    if (!window)
        return;
    if (button == BTN_LEFT)
    {
        switch (window->wl.decorations.focus)
        {
            case mainWindow:
                break;
            case topDecoration:
                if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
                    edges = WL_SHELL_SURFACE_RESIZE_TOP;
                else
                {
                    if (window->wl.xdg.toplevel)
                        xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
                    else
                        wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial);
                }
                break;
            case leftDecoration:
                if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
                    edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
                else
                    edges = WL_SHELL_SURFACE_RESIZE_LEFT;
                break;
            case rightDecoration:
                if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
                    edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
                else
                    edges = WL_SHELL_SURFACE_RESIZE_RIGHT;
                break;
            case bottomDecoration:
                if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
                    edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
                else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
                    edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
                else
                    edges = WL_SHELL_SURFACE_RESIZE_BOTTOM;
                break;
            default:
                assert(0);
        }
        if (edges != WL_SHELL_SURFACE_RESIZE_NONE)
        {
            if (window->wl.xdg.toplevel)
                xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
                                    serial, edges);
            else
                wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat,
                                        serial, edges);
        }
    }
    else if (button == BTN_RIGHT)
    {
        if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)
        {
            xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
                                          _glfw.wl.seat, serial,
                                          window->wl.cursorPosX,
                                          window->wl.cursorPosY);
            return;
        }
    }

    // Don’t pass the button to the user if it was related to a decoration.
    if (window->wl.decorations.focus != mainWindow)
        return;

    _glfw.wl.pointerSerial = serial;

    /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
     * codes. */
    glfwButton = button - BTN_LEFT;

    _glfwInputMouseClick(window,
                         glfwButton,
                         state == WL_POINTER_BUTTON_STATE_PRESSED
                                ? GLFW_PRESS
                                : GLFW_RELEASE,
                         _glfw.wl.xkb.modifiers);
}
Esempio n. 19
0
// Window callback function (handles window messages)
//
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam)
{
    _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0);
    if (!window)
    {
        switch (uMsg)
        {
            case WM_NCCREATE:
            {
                CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam;
                SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams);
                break;
            }

            case WM_DEVICECHANGE:
            {
                if (wParam == DBT_DEVNODES_CHANGED)
                {
                    _glfwInputMonitorChange();
                    return TRUE;
                }

                break;
            }
        }

        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
    }

    switch (uMsg)
    {
        case WM_SETFOCUS:
        {
            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);

            _glfwInputWindowFocus(window, GLFW_TRUE);
            return 0;
        }

        case WM_KILLFOCUS:
        {
            if (window->cursorMode == GLFW_CURSOR_DISABLED)
                _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);

            if (window->monitor && window->autoIconify)
                _glfwPlatformIconifyWindow(window);

            _glfwInputWindowFocus(window, GLFW_FALSE);
            return 0;
        }

        case WM_SYSCOMMAND:
        {
            switch (wParam & 0xfff0)
            {
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:
                {
                    if (window->monitor)
                    {
                        // We are running in full screen mode, so disallow
                        // screen saver and screen blanking
                        return 0;
                    }
                    else
                        break;
                }

                // User trying to access application menu using ALT?
                case SC_KEYMENU:
                    return 0;
            }
            break;
        }

        case WM_CLOSE:
        {
            _glfwInputWindowCloseRequest(window);
            return 0;
        }

        case WM_CHAR:
        case WM_SYSCHAR:
        case WM_UNICHAR:
        {
            const GLFWbool plain = (uMsg != WM_SYSCHAR);

            if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
            {
                // WM_UNICHAR is not sent by Windows, but is sent by some
                // third-party input method engine
                // Returning TRUE here announces support for this message
                return TRUE;
            }

            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
            return 0;
        }

        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
        {
            const int key = translateKey(wParam, lParam);
            const int scancode = (lParam >> 16) & 0x1ff;
            const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
            const int mods = getKeyMods();

            if (key == _GLFW_KEY_INVALID)
                break;

            if (action == GLFW_RELEASE && wParam == VK_SHIFT)
            {
                // Release both Shift keys on Shift up event, as only one event
                // is sent even if both keys are released
                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
            }
            else if (wParam == VK_SNAPSHOT)
            {
                // Key down is not reported for the Print Screen key
                _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
            }
            else
                _glfwInputKey(window, key, scancode, action, mods);

            break;
        }

        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:
        case WM_XBUTTONDOWN:
        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
        case WM_MBUTTONUP:
        case WM_XBUTTONUP:
        {
            int button, action;

            if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
                button = GLFW_MOUSE_BUTTON_LEFT;
            else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
                button = GLFW_MOUSE_BUTTON_RIGHT;
            else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
                button = GLFW_MOUSE_BUTTON_MIDDLE;
            else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
                button = GLFW_MOUSE_BUTTON_4;
            else
                button = GLFW_MOUSE_BUTTON_5;

            if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN ||
                uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
            {
                action = GLFW_PRESS;
                SetCapture(hWnd);
            }
            else
            {
                action = GLFW_RELEASE;
                ReleaseCapture();
            }

            _glfwInputMouseClick(window, button, action, getKeyMods());

            if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
                return TRUE;

            return 0;
        }

        case WM_MOUSEMOVE:
        {
            const int x = GET_X_LPARAM(lParam);
            const int y = GET_Y_LPARAM(lParam);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
            {
                if (_glfw.cursorWindow != window)
                    break;

                _glfwInputCursorMotion(window,
                                       x - window->win32.cursorPosX,
                                       y - window->win32.cursorPosY);
            }
            else
                _glfwInputCursorMotion(window, x, y);

            window->win32.cursorPosX = x;
            window->win32.cursorPosY = y;

            if (!window->win32.cursorTracked)
            {
                TRACKMOUSEEVENT tme;
                ZeroMemory(&tme, sizeof(tme));
                tme.cbSize = sizeof(tme);
                tme.dwFlags = TME_LEAVE;
                tme.hwndTrack = window->win32.handle;
                TrackMouseEvent(&tme);

                window->win32.cursorTracked = GLFW_TRUE;
                _glfwInputCursorEnter(window, GLFW_TRUE);
            }

            return 0;
        }

        case WM_MOUSELEAVE:
        {
            window->win32.cursorTracked = GLFW_FALSE;
            _glfwInputCursorEnter(window, GLFW_FALSE);
            return 0;
        }

        case WM_MOUSEWHEEL:
        {
            _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
            return 0;
        }

        case WM_MOUSEHWHEEL:
        {
            // This message is only sent on Windows Vista and later
            // NOTE: The X-axis is inverted for consistency with OS X and X11.
            _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
            return 0;
        }

        case WM_SIZE:
        {
            if (_glfw.cursorWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
            {
                window->win32.iconified = GLFW_TRUE;
                if (window->monitor)
                    leaveFullscreenMode(window);

                _glfwInputWindowIconify(window, GLFW_TRUE);
            }
            else if (window->win32.iconified &&
                     (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
            {
                window->win32.iconified = GLFW_FALSE;
                if (window->monitor)
                    enterFullscreenMode(window);

                _glfwInputWindowIconify(window, GLFW_FALSE);
            }

            _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
            _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
            return 0;
        }

        case WM_MOVE:
        {
            if (_glfw.cursorWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
            // those macros do not handle negative window positions correctly
            _glfwInputWindowPos(window,
                                GET_X_LPARAM(lParam),
                                GET_Y_LPARAM(lParam));
            return 0;
        }

        case WM_SIZING:
        {
            if (window->win32.numer == GLFW_DONT_CARE ||
                window->win32.denom == GLFW_DONT_CARE)
            {
                break;
            }

            applyAspectRatio(window, (int) wParam, (RECT*) lParam);
            return TRUE;
        }

        case WM_GETMINMAXINFO:
        {
            int xoff, yoff;
            MINMAXINFO* mmi = (MINMAXINFO*) lParam;

            getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
                              0, 0, &xoff, &yoff);

            if (window->win32.minwidth != GLFW_DONT_CARE &&
                window->win32.minheight != GLFW_DONT_CARE)
            {
                mmi->ptMinTrackSize.x = window->win32.minwidth + xoff;
                mmi->ptMinTrackSize.y = window->win32.minheight + yoff;
            }

            if (window->win32.maxwidth != GLFW_DONT_CARE &&
                window->win32.maxheight != GLFW_DONT_CARE)
            {
                mmi->ptMaxTrackSize.x = window->win32.maxwidth + xoff;
                mmi->ptMaxTrackSize.y = window->win32.maxheight + yoff;
            }

            return 0;
        }

        case WM_PAINT:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case WM_ERASEBKGND:
        {
            return TRUE;
        }

        case WM_SETCURSOR:
        {
            if (_glfw.cursorWindow == window && LOWORD(lParam) == HTCLIENT)
            {
                if (window->cursorMode == GLFW_CURSOR_HIDDEN ||
                    window->cursorMode == GLFW_CURSOR_DISABLED)
                {
                    SetCursor(NULL);
                    return TRUE;
                }
                else if (window->cursor)
                {
                    SetCursor(window->cursor->win32.handle);
                    return TRUE;
                }
            }

            break;
        }

        case WM_DPICHANGED:
        {
            RECT* rect = (RECT*) lParam;
            SetWindowPos(window->win32.handle,
                         HWND_TOP,
                         rect->left,
                         rect->top,
                         rect->right - rect->left,
                         rect->bottom - rect->top,
                         SWP_NOACTIVATE | SWP_NOZORDER);
            break;
        }

        case WM_DROPFILES:
        {
            HDROP drop = (HDROP) wParam;
            POINT pt;
            int i;

            const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
            char** paths = calloc(count, sizeof(char*));

            // Move the mouse to the position of the drop
            DragQueryPoint(drop, &pt);
            _glfwInputCursorMotion(window, pt.x, pt.y);

            for (i = 0;  i < count;  i++)
            {
                const UINT length = DragQueryFileW(drop, i, NULL, 0);
                WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));

                DragQueryFileW(drop, i, buffer, length + 1);
                paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);

                free(buffer);
            }

            _glfwInputDrop(window, count, (const char**) paths);

            for (i = 0;  i < count;  i++)
                free(paths[i]);
            free(paths);

            DragFinish(drop);
            return 0;
        }
    }

    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}