bool EventHandler::_mouseButtonRelease(const PointerButton button, const LPARAM lParam) { PointerEvent pointerEvent; _buttonState &= ~button; pointerEvent.x = GET_X_LPARAM(lParam); pointerEvent.y = GET_Y_LPARAM(lParam); pointerEvent.buttons = _buttonState; pointerEvent.button = button; pointerEvent.modifiers = _getKeyModifiers(); _computePointerDelta(EVENT_WINDOW_POINTER_BUTTON_RELEASE, pointerEvent); return _window->processEvent(EVENT_WINDOW_POINTER_BUTTON_RELEASE, pointerEvent); }
bool EventHandler::_processEvent( const XEvent& event ) { LB_TS_THREAD( _thread ); XID drawable = event.xany.window; if( _window->getXDrawable() != drawable ) return false; switch( event.type ) { case Expose: if( event.xexpose.count ) // Only report last expose event return true; return _window->processEvent( EVENT_WINDOW_EXPOSE, event ); case ConfigureNotify: { SizeEvent sizeEvent; _getWindowSize( event.xany.display, drawable, sizeEvent ); return _window->processEvent( EVENT_WINDOW_RESIZE, event, sizeEvent ); } case UnmapNotify: { SizeEvent sizeEvent; _getWindowSize( event.xany.display, drawable, sizeEvent ); return _window->processEvent( EVENT_WINDOW_HIDE, event, sizeEvent ); } case MapNotify: { SizeEvent sizeEvent; _getWindowSize( event.xany.display, drawable, sizeEvent ); return _window->processEvent( EVENT_WINDOW_SHOW, event, sizeEvent ); } case ClientMessage: { #ifdef EQUALIZER_USE_MAGELLAN_GLX spnav_event spev; if( spnav_x11_event( &event, &spev )) // spacenav event { switch( spev.type ) { case SPNAV_EVENT_MOTION: { AxisEvent axisEvent; axisEvent.xAxis = spev.motion.x; axisEvent.yAxis = spev.motion.y; axisEvent.zAxis = -spev.motion.z; axisEvent.xRotation = -spev.motion.rx; axisEvent.yRotation = -spev.motion.ry; axisEvent.zRotation = spev.motion.rz; return _window->processEvent( event, axisEvent ); } case SPNAV_EVENT_BUTTON: { ButtonEvent buttonEvent; buttonEvent.buttons = spev.button.press; buttonEvent.button = spev.button.bnum; return _window->processEvent( event, buttonEvent ); } default: LBUNIMPLEMENTED; return false; } break; } #endif Atom deleteAtom = XInternAtom( event.xany.display, "WM_DELETE_WINDOW", False ); if( static_cast<Atom>( event.xclient.data.l[0] ) != deleteAtom ) return false; // not a delete message, ignore. } // else: delete message, fall through case DestroyNotify: return _window->processEvent( EVENT_WINDOW_CLOSE, event ); case MotionNotify: { PointerEvent pointerEvent; pointerEvent.x = event.xmotion.x; pointerEvent.y = event.xmotion.y; pointerEvent.buttons = _getButtonState( event ); pointerEvent.button = PTR_BUTTON_NONE; pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state ); _computePointerDelta( EVENT_WINDOW_POINTER_MOTION, pointerEvent ); return _window->processEvent( EVENT_WINDOW_POINTER_MOTION, event, pointerEvent ); } case ButtonPress: { PointerEvent pointerEvent; pointerEvent.x = event.xbutton.x; pointerEvent.y = event.xbutton.y; pointerEvent.buttons = _getButtonState( event ); pointerEvent.button = _getButtonAction( event ); pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state ); switch( pointerEvent.button ) // Translate wheel events { case PTR_BUTTON4: pointerEvent.yAxis = 1; break; case PTR_BUTTON5: pointerEvent.yAxis = -1; break; case PTR_BUTTON6: pointerEvent.xAxis = 1; break; case PTR_BUTTON7: pointerEvent.xAxis = -1; break; } switch( pointerEvent.button ) { case PTR_BUTTON4: case PTR_BUTTON5: case PTR_BUTTON6: case PTR_BUTTON7: pointerEvent.button = PTR_BUTTON_NONE; _computePointerDelta( EVENT_WINDOW_POINTER_WHEEL, pointerEvent ); return _window->processEvent( EVENT_WINDOW_POINTER_WHEEL, event, pointerEvent ); } _computePointerDelta( EVENT_WINDOW_POINTER_BUTTON_PRESS, pointerEvent ); return _window->processEvent( EVENT_WINDOW_POINTER_BUTTON_PRESS, event, pointerEvent ); } case ButtonRelease: { PointerEvent pointerEvent; pointerEvent.x = event.xbutton.x; pointerEvent.y = event.xbutton.y; pointerEvent.buttons = _getButtonState( event ); pointerEvent.button = _getButtonAction( event); pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state ); _computePointerDelta( EVENT_WINDOW_POINTER_BUTTON_RELEASE, pointerEvent ); return _window->processEvent( EVENT_WINDOW_POINTER_BUTTON_RELEASE, event, pointerEvent ); } case KeyPress: { KeyEvent keyEvent; keyEvent.key = _getKey( event ); keyEvent.modifiers = _getKeyModifiers( event.xkey.state ); return _window->processEvent( EVENT_KEY_PRESS, event, keyEvent ); } case KeyRelease: { KeyEvent keyEvent; keyEvent.key = _getKey( event ); keyEvent.modifiers = _getKeyModifiers( event.xkey.state ); return _window->processEvent( EVENT_KEY_RELEASE, event, keyEvent ); } default: LBWARN << "Unhandled X event, type " << event.type << std::endl; // no break; case ReparentNotify: case VisibilityNotify: return _window->processEvent( EVENT_UNKNOWN, event ); } }
LRESULT CALLBACK EventHandler::_wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SHOWWINDOW: { SizeEvent sizeEvent; _getWindowSize(hWnd, sizeEvent); EventType type = wParam == TRUE ? EVENT_WINDOW_SHOW : EVENT_WINDOW_HIDE; if (_window->processEvent(type, sizeEvent)) return TRUE; break; } case WM_CREATE: case WM_SIZE: case WM_MOVE: case WM_WINDOWPOSCHANGED: { SizeEvent sizeEvent; _getWindowSize(hWnd, sizeEvent); const bool hasArea = (sizeEvent.w > 0 && sizeEvent.h > 0); const PixelViewport& pvp = _window->getPixelViewport(); // No show/hide events on Win32?: Emulate. EventType type; if (!hasArea && pvp.hasArea()) type = EVENT_WINDOW_HIDE; else if (hasArea && !pvp.hasArea()) type = EVENT_WINDOW_SHOW; else type = EVENT_WINDOW_RESIZE; if (_window->processEvent(type, sizeEvent)) return TRUE; break; } case WM_CLOSE: case WM_DESTROY: { if (_window->processEvent(EVENT_WINDOW_CLOSE)) return TRUE; break; } case WM_PAINT: { if (GetUpdateRect(hWnd, 0, false) == 0) // No 'expose' return DefWindowProc(hWnd, uMsg, wParam, lParam); if (_window->processEvent(EVENT_WINDOW_EXPOSE)) return TRUE; break; } case WM_MOUSEMOVE: { _syncButtonState(wParam); PointerEvent pointerEvent; pointerEvent.x = GET_X_LPARAM(lParam); pointerEvent.y = GET_Y_LPARAM(lParam); pointerEvent.buttons = _buttonState; _computePointerDelta(EVENT_WINDOW_POINTER_MOTION, pointerEvent); if (_window->processEvent(EVENT_WINDOW_POINTER_MOTION, pointerEvent)) return TRUE; break; } case WM_LBUTTONDOWN: if (_mouseButtonPress(PTR_BUTTON1, lParam)) return TRUE; break; case WM_RBUTTONDOWN: if (_mouseButtonPress(PTR_BUTTON2, lParam)) return TRUE; break; case WM_MBUTTONDOWN: if (_mouseButtonPress(PTR_BUTTON3, lParam)) return TRUE; break; case WM_XBUTTONDOWN: { const PointerButton button = GET_XBUTTON_WPARAM(wParam) & XBUTTON1 ? PTR_BUTTON4 : PTR_BUTTON5; _syncButtonState(GET_XBUTTON_WPARAM(wParam)); if (_mouseButtonPress(button, lParam)) return TRUE; break; } case WM_LBUTTONUP: if (_mouseButtonRelease(PTR_BUTTON1, lParam)) return TRUE; break; case WM_RBUTTONUP: if (_mouseButtonRelease(PTR_BUTTON2, lParam)) return TRUE; break; case WM_MBUTTONUP: if (_mouseButtonRelease(PTR_BUTTON3, lParam)) return TRUE; break; case WM_XBUTTONUP: { const PointerButton button = GET_XBUTTON_WPARAM(wParam) & XBUTTON1 ? PTR_BUTTON4 : PTR_BUTTON5; _syncButtonState(GET_XBUTTON_WPARAM(wParam)); if (_mouseButtonRelease(button, lParam)) return TRUE; break; } case WM_MOUSEWHEEL: { PointerEvent pointerEvent; pointerEvent.x = GET_X_LPARAM(lParam); pointerEvent.y = GET_Y_LPARAM(lParam); pointerEvent.buttons = _buttonState; pointerEvent.modifiers = _getKeyModifiers(); pointerEvent.yAxis = _getWheelDelta(wParam); pointerEvent.button = PTR_BUTTON_NONE; _computePointerDelta(EVENT_WINDOW_POINTER_WHEEL, pointerEvent); if (_window->processEvent(EVENT_WINDOW_POINTER_WHEEL, pointerEvent)) return TRUE; break; } #ifdef WM_MOUSEHWHEEL // only available on vista or later case WM_MOUSEHWHEEL: { PointerEvent pointerEvent; pointerEvent.x = GET_X_LPARAM(lParam); pointerEvent.y = GET_Y_LPARAM(lParam); pointerEvent.buttons = _buttonState; pointerEvent.modifiers = _getKeyModifiers(); pointerEvent.xAxis = _getWheelDelta(wParam); pointerEvent.button = PTR_BUTTON_NONE; _computePointerDelta(EVENT_WINDOW_POINTER_WHEEL, pointerEvent); if (_window->processEvent(EVENT_WINDOW_POINTER_WHEEL, pointerEvent)) return TRUE; break; } #endif case WM_SYSKEYDOWN: case WM_KEYDOWN: { KeyEvent keyEvent; keyEvent.key = _getKey(lParam, wParam); keyEvent.modifiers = _getKeyModifiers(); if (_window->processEvent(EVENT_KEY_PRESS, keyEvent)) return TRUE; break; } case WM_SYSKEYUP: case WM_KEYUP: { KeyEvent keyEvent; keyEvent.key = _getKey(lParam, wParam); keyEvent.modifiers = _getKeyModifiers(); if (_window->processEvent(EVENT_KEY_RELEASE, keyEvent)) return TRUE; break; } case WM_SYSCOMMAND: switch (wParam) { case SC_MONITORPOWER: case SC_SCREENSAVE: if (lParam >= 0) // request off { if (_window->processEvent(EVENT_WINDOW_SCREENSAVER)) return TRUE; break; } // else no break; fall through default: _window->processEvent(EVENT_UNKNOWN); LBVERB << "Unhandled system command 0x" << std::hex << wParam << std::dec << std::endl; break; } break; #ifdef EQUALIZER_USE_MAGELLAN case WM_INPUT: _magellanEventHandler(lParam); break; #endif default: _window->processEvent(EVENT_UNKNOWN); LBVERB << "Unhandled message 0x" << std::hex << uMsg << std::dec << std::endl; break; } return CallWindowProc(_prevWndProc, hWnd, uMsg, wParam, lParam); }