void OptionKey::Render() { WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT); mFont->SetColor(getColor(WGuiColor::TEXT)); JRenderer * renderer = JRenderer::GetInstance(); if (LOCAL_KEY_NONE == from) { string msg = _("New binding..."); mFont->DrawString(msg, (SCREEN_WIDTH - mFont->GetStringWidth(msg.c_str())) / 2, y + 2); } else { const KeyRep& rep = translateKey(from); if (rep.second) renderer->RenderQuad(rep.second, x + 4, y + 3, 0, 16.0f / rep.second->mHeight, 16.0f / rep.second->mHeight); else mFont->DrawString(rep.first, x + 4, y + 3, JGETEXT_LEFT); const KeyRep& rep2 = translateKey(to); if (rep2.second) { float ratio = 16.0f / rep2.second->mHeight; renderer->RenderQuad(rep2.second, x + width - (ratio * rep2.second->mWidth) - 2, y + 3, 0, ratio, ratio); } else mFont->DrawString(rep2.first, width - 4, y + 3, JGETEXT_RIGHT); } }
void ConfigurationMapper::enumerate(const std::string& key, Keys& range) const { std::string cKey(key); if (!cKey.empty()) cKey += '.'; std::string::size_type keyLen = cKey.length(); if (keyLen < _toPrefix.length()) { if (_toPrefix.compare(0, keyLen, cKey) == 0) { std::string::size_type pos = _toPrefix.find_first_of('.', keyLen); poco_assert_dbg(pos != std::string::npos); range.push_back(_toPrefix.substr(keyLen, pos - keyLen)); } } else { std::string translatedKey; if (cKey == _toPrefix) { translatedKey = _fromPrefix; if (!translatedKey.empty()) translatedKey.resize(translatedKey.length() - 1); } else translatedKey = translateKey(key); _pConfig->enumerate(translatedKey, range); } }
LONG WINAPI QuackWin::MainWndProc(HWND n_hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: { LPCREATESTRUCT cs = reinterpret_cast<LPCREATESTRUCT>(lParam); void * lpCreateParam = cs->lpCreateParams; QuackWin *win = reinterpret_cast<QuackWin *>(lpCreateParam); assert(win == this); return DefWindowProc(hWnd, uMsg, wParam, lParam); } case WM_CHAR: case WM_KEYDOWN: case WM_SYSCHAR: case WM_UNICHAR: case WM_SYSKEYDOWN: { const char key = translateKey(wParam, lParam); if (key == 0) break; input->HandleKeyPress(key); break; } } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
int16 Util::checkKey() { Common::KeyState key; getKeyFromBuffer(key); return translateKey(key); }
BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key) { if(mNumpadDistinct == ND_NUMLOCK_ON) { std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key); if (iter != mTranslateNumpadMap.end()) { *translated_key = iter->second; return TRUE; } } BOOL success = translateKey(os_key, translated_key); if(mNumpadDistinct != ND_NEVER) { if(!success) return success; if(mask & MASK_EXTENDED) { // this is where we'd create new keycodes for extended keys // the set of extended keys includes the 'normal' arrow keys and // the pgup/dn/insert/home/end/delete cluster above the arrow keys // see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx // only process the return key if numlock is off if(((mNumpadDistinct == ND_NUMLOCK_OFF && !(GetKeyState(VK_NUMLOCK) & 1)) || mNumpadDistinct == ND_NUMLOCK_ON) && *translated_key == KEY_RETURN) { *translated_key = KEY_PAD_RETURN; } } else { // the non-extended keys, those are in the numpad switch (*translated_key) { case KEY_LEFT: *translated_key = KEY_PAD_LEFT; break; case KEY_RIGHT: *translated_key = KEY_PAD_RIGHT; break; case KEY_UP: *translated_key = KEY_PAD_UP; break; case KEY_DOWN: *translated_key = KEY_PAD_DOWN; break; case KEY_HOME: *translated_key = KEY_PAD_HOME; break; case KEY_END: *translated_key = KEY_PAD_END; break; case KEY_PAGE_UP: *translated_key = KEY_PAD_PGUP; break; case KEY_PAGE_DOWN: *translated_key = KEY_PAD_PGDN; break; case KEY_INSERT: *translated_key = KEY_PAD_INS; break; case KEY_DELETE: *translated_key = KEY_PAD_DEL; break; } } } return success; }
void eLircInputDevice::handleCode(long arg) { const lircEvent* event = (const lircEvent*)arg; int code, flags; if (event->repeat == true) { flags = eRCKey::flagRepeat; } else if (event->release == true) { flags = eRCKey::flagBreak; } else { flags = eRCKey::flagMake; } code = translateKey(event->name); eDebug("LIRC name=%s code=%d flags=%d", event->name, code, flags); input->keyPressed(eRCKey(this, code, flags)); if (flags == eRCKey::flagMake) { flags = eRCKey::flagBreak; eDebug("LIRC name=%s code=%d flags=%d", event->name, code, flags); input->keyPressed(eRCKey(this, code, flags)); flags = eRCKey::flagMake; } }
// // ISDL12KeyboardInputDevice::gatherEvents // // Pumps the SDL Event queue and retrieves any mouse events and puts them into // this instance's event queue. // void ISDL12KeyboardInputDevice::gatherEvents() { if (!active()) return; // Force SDL to gather events from input devices. This is called // implicitly from SDL_PollEvent but since we're using SDL_PeepEvents to // process only mouse events, SDL_PumpEvents is necessary. SDL_PumpEvents(); // Retrieve chunks of up to 1024 events from SDL int num_events = 0; const int max_events = 1024; SDL_Event sdl_events[max_events]; bool quit_event = false; while ((num_events = SDL_PeepEvents(sdl_events, max_events, SDL_GETEVENT, SDL_KEYEVENTMASK))) { for (int i = 0; i < num_events; i++) { const SDL_Event& sdl_ev = sdl_events[i]; assert(sdl_ev.type == SDL_KEYDOWN || sdl_ev.type == SDL_KEYUP); if (sdl_ev.key.keysym.sym == SDLK_F4 && sdl_ev.key.keysym.mod & (KMOD_LALT | KMOD_RALT)) { // HeX9109: Alt+F4 for cheats! Thanks Spleen // [SL] Don't handle it here but make sure we indicate there was an ALT+F4 event. quit_event = true; } else if (sdl_ev.key.keysym.sym == SDLK_TAB && sdl_ev.key.keysym.mod & (KMOD_LALT | KMOD_RALT)) { // do nothing - the event is dropped } else { // Normal game keyboard event - insert it into our internal queue event_t ev; ev.type = (sdl_ev.type == SDL_KEYDOWN) ? ev_keydown : ev_keyup; ev.data1 = translateKey(sdl_ev.key.keysym.sym); ev.data2 = ev.data3 = translateKeyText(sdl_ev.key.keysym.sym, sdl_ev.key.keysym.mod); if (ev.data1) mEvents.push(ev); } } } // Translate the ALT+F4 key combo event into a SDL_QUIT event and push // it back into SDL's event queue so that it can be handled elsewhere. if (quit_event) { SDL_Event sdl_ev; sdl_ev.type = SDL_QUIT; SDL_PushEvent(&sdl_ev); } }
void InputHandler::_processKeyPress( int nativeKeyCode, int64_t timestamp ) { // Verify that this key isn't already pressed for( auto i : m_keysDown ) { if( i.nativeKeyCode == nativeKeyCode ) return; } // Key translatedKeyCode = translateKey(nativeKeyCode); // Create and fill in the info-structure. KeyDownInfo info; info.nativeKeyCode = nativeKeyCode; info.translatedKeyCode = translatedKeyCode; info.pressTimestamp = timestamp; info.pWidget = _focusedWidget(); m_keysDown.push_back( info ); // Post KEY_PRESS message Widget * pWidget = _focusedWidget(); Base::msgRouter()->post( new KeyPressMsg( m_inputId, nativeKeyCode, translatedKeyCode, pWidget, m_modKeys, m_pointerPos, timestamp ) ); // Post an EditCommand if that is associated with the key-combo. EditCmd cmd = translateCommand( nativeKeyCode, m_modKeys ); if( cmd != EditCmd::None ) Base::msgRouter()->post( new EditCommandMsg( m_inputId, cmd, pWidget )); // Update modkeys switch( translatedKeyCode ) { case Key::Shift: m_modKeys = (ModifierKeys) (m_modKeys | MODKEY_SHIFT); break; case Key::Control: m_modKeys = (ModifierKeys) (m_modKeys | MODKEY_CTRL); break; case Key::Alt: m_modKeys = (ModifierKeys) (m_modKeys | MODKEY_ALT); break; case Key::Super: m_modKeys = (ModifierKeys) (m_modKeys | MODKEY_SUPER); break; default: break; } }
bool Util::checkKey(int16 &key) { Common::KeyState keyS; if (!getKeyFromBuffer(keyS)) return false; key = translateKey(keyS); return true; }
void WebWindow::onKeyUp(CEGUI::KeyEventArgs& e) { UINT vk = translateKey(e.scancode); if (vk) { e.handled = d_webView->keyUp(vk, 0, false); } CEGUI::Window::onKeyUp(e); }
void eSDLInputDevice::handleCode(long arg) { const SDL_KeyboardEvent *event = (const SDL_KeyboardEvent *)arg; const SDL_keysym *key = &event->keysym; int km = input->getKeyboardMode(); int code, flags; if (event->type == SDL_KEYDOWN) { m_unicode = key->unicode; flags = eRCKey::flagMake; } else { flags = eRCKey::flagBreak; } if (km == eRCInput::kmNone) { code = translateKey(key->sym); } else { eDebug("unicode=%04x scancode=%02x", m_unicode, key->scancode); if (m_unicode & 0xff80) { eDebug("SDL: skipping unicode character"); return; } code = m_unicode & ~0xff80; // unicode not set...!? use key symbol if (code == 0) { // keysym is ascii if (key->sym >= 128) { eDebug("SDL: cannot emulate ASCII"); return; } eDebug("SDL: emulate ASCII"); code = key->sym; } if (km == eRCInput::kmAscii) { // skip ESC c or ESC '[' c if (m_escape) { if (code != '[') m_escape = false; return; } if (code == SDLK_ESCAPE) m_escape = true; if ((code < SDLK_SPACE) || (code == 0x7e) || // really? (code == SDLK_DELETE)) return; } flags |= eRCKey::flagAscii; } eDebug("SDL code=%d flags=%d", code, flags); input->keyPressed(eRCKey(this, code, flags)); }
int16 Util::getKey() { Common::KeyState key; while (!getKeyFromBuffer(key)) { processInput(); if (keyBufferEmpty()) g_system->delayMillis(10 / _vm->_global->_speedFactor); } return translateKey(key); }
void GfxGLWindowGLUT::keyboardCB( unsigned char key, int x, int y ) { GfxGLWindowGLUT& window = getWindow(); KeyID keyId = translateKey( key ); ModBitfield mods = getModifiers(); // FIXME: what does GLUT's key CB correspond to? keydown, or // key press? //window.keyDownReceived( keyId, mods ); window.keyPressed( keyId, mods ); window.handleMiscEvents(); }
void OptionKey::KeyPressed(LocalKeySym key) { from = key; g->UngrabKeyboard(this); grabbed = false; btnMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), 0, this, Fonts::MENU_FONT, 80, 10); for (int i = sizeof(btnList) / sizeof(btnList[0]) - 1; i >= 0; --i) { const KeyRep& rep = translateKey(btnList[i]); btnMenu->Add(i, rep.first.c_str()); } }
BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key ) { if(mNumpadDistinct == ND_NUMLOCK_ON) { std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); if(iter != mTranslateNumpadMap.end()) { *translated_key = iter->second; return TRUE; } } return translateKey(os_key, translated_key); }
void SdlContext::processKeyboardEvent( SDL_KeyboardEvent& event ) { if(event.type != SDL_KEYDOWN) return; unsigned int key= translateKey(event.keysym.sym); if(key == 0) return; int x, y; SDL_GetMouseState(&x, &y); //~ printf("widgets: scan 0x%x '%c' key %c %d, key name %s\n", event.keysym.scancode, event.keysym.scancode, event.keysym.sym, translateKey(event.keysym.sym), SDL_GetKeyName(event.keysym.sym)); UIContext::keyboard(key, x, y); }
void QWaylandInputDevice::inputHandleKey(void *data, struct wl_input_device *input_device, uint32_t time, uint32_t key, uint32_t state) { #ifndef QT_NO_WAYLAND_XKB Q_UNUSED(input_device); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mKeyboardFocus; uint32_t code, sym, level; Qt::KeyboardModifiers modifiers; QEvent::Type type; char s[2]; if (window == NULL) { /* We destroyed the keyboard focus surface, but the server * didn't get the message yet. */ return; } code = key + inputDevice->mXkb->min_key_code; level = 0; if (inputDevice->mModifiers & Qt::ShiftModifier && XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1) level = 1; sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0); modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]); if (state) { inputDevice->mModifiers |= modifiers; type = QEvent::KeyPress; } else { inputDevice->mModifiers &= ~modifiers; type = QEvent::KeyRelease; } sym = translateKey(sym, s, sizeof s); if (window) { QWindowSystemInterface::handleKeyEvent(window->widget(), time, type, sym, inputDevice->mModifiers, QString::fromLatin1(s)); } #endif }
void SP_PollEvents(void) { SDL_Event event; while(SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { pleaseExit = true; } else if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { boolean down = event.type == SDL_KEYDOWN; if (down && event.key.keysym.sym == SDLK_m) { // override mouse grabbing toggleMouseGrab(); } int idKey = translateKey(event.key.keysym.sym); if (idKey != 0) { SPI_InputKey(idKey, down); } char c=0; if ((event.key.keysym.unicode&0xFF80) == 0) { c = event.key.keysym.unicode&0x7F; } if (down && c != 0) { SPI_InputASCII(c); } } else if (event.type == SDL_MOUSEMOTION) { SPI_InputMouseMotion(event.motion.xrel,event.motion.yrel); } else if (event.type == SDL_MOUSEBUTTONDOWN) { if (event.button.button == SDL_BUTTON_LEFT) { SPI_InputKey(but_Mouse1, 1); } else if (event.button.button == SDL_BUTTON_RIGHT) { SPI_InputKey(but_Mouse2, 1); } else if (event.button.button == SDL_BUTTON_MIDDLE) { SPI_InputKey(but_Mouse3, 1); } } else if (event.type == SDL_MOUSEBUTTONUP) { if (event.button.button == SDL_BUTTON_LEFT) { SPI_InputKey(but_Mouse1, 0); } else if (event.button.button == SDL_BUTTON_RIGHT) { SPI_InputKey(but_Mouse2, 0); } else if (event.button.button == SDL_BUTTON_MIDDLE) { SPI_InputKey(but_Mouse3, 0); } } else if (event.type == SDL_VIDEORESIZE) { SDL_ResizeEvent *resize = (SDL_ResizeEvent*)&event; SPG_SetWindowSize(resize->w, resize->h); } } }
//-------------------------------------------------------------- // handle key release void mgWinServices::keyUp( WPARAM wParam, LPARAM lParam) { if (wParam == VK_SHIFT) m_eventFlags &= ~MG_EVENT_SHIFT_DOWN; else if (wParam == VK_CONTROL) m_eventFlags &= ~MG_EVENT_CNTL_DOWN; else if (wParam == VK_MENU) m_eventFlags &= ~MG_EVENT_ALT_DOWN; // translate special keys int key = translateKey((int) wParam); if (m_theApp != NULL) { m_theApp->appKeyUp(key, m_eventFlags); } }
void InputHandler::_processKeyRelease( int nativeKeyCode, int64_t timestamp ) { // Find right KeyDownInfo structure and remove it from m_keysDown. auto it = m_keysDown.begin(); while( it != m_keysDown.end() ) { if( nativeKeyCode == it->nativeKeyCode ) { m_keysDown.erase(it); break; } it++; } // Post KEY_RELEASE message Key translatedKeyCode = translateKey(nativeKeyCode); Widget * pWidget = _focusedWidget(); Base::msgRouter()->post( new KeyReleaseMsg( m_inputId, nativeKeyCode, translatedKeyCode, pWidget, m_modKeys, m_pointerPos, timestamp ) ); // Update modkeys switch( translatedKeyCode ) { case Key::Shift: m_modKeys = (ModifierKeys) (m_modKeys & ~MODKEY_SHIFT); break; case Key::Control: m_modKeys = (ModifierKeys) (m_modKeys & ~MODKEY_CTRL); break; case Key::Alt: m_modKeys = (ModifierKeys) (m_modKeys & ~MODKEY_ALT); break; case Key::Super: m_modKeys = (ModifierKeys) (m_modKeys & ~MODKEY_SUPER); break; default: break; } }
/** \brief The GUI's key press event handler. * * This function should be called from the SDL event loop. It takes a keyboard event * as an argument, translates it to PUI syntax and passes it to the * PUI-internal keyboard function. If there's no active widget which could * use the key event the function will return false, giving the caller * the opportunity to use the event for other purposes. * \param key A key symbol generated by an SDL keyboard event. * \return true if PUI was able to handle the event */ bool CGUIMain::keyDownEventHandler(SDL_keysym& key) { int tkey; bool ret; tkey = translateKey(key); ret = puKeyboard(tkey, PU_DOWN); // ESC key handling // note: translateKey() does not affect the ESC keysym, // so it is safe to test the SDL key value here if (!ret && (tkey == SDLK_ESCAPE)) { if (isVisible()) { CRRCDialog* top = CRRCDialog::getToplevel(); if (top != NULL) { if (top->hasCancelButton()) { //std::cout << "Invoking CANCEL for toplevel dialog" << std::endl; top->setValue(CRRC_DIALOG_CANCEL); top->invokeCallback(); } } else { //std::cout << "No active dialog, hiding GUI" << std::endl; hide(); } } else { reveal(); } ret = true; } return ret; }
void ServerProxy::keyUp() { // get mouse up to date flushCompressedMouse(); // parse UInt16 id, mask, button; ProtocolUtil::readf(m_stream, kMsgDKeyUp + 4, &id, &mask, &button); LOG((CLOG_DEBUG1 "recv key up id=0x%08x, mask=0x%04x, button=0x%04x", id, mask, button)); // translate KeyID id2 = translateKey(static_cast<KeyID>(id)); KeyModifierMask mask2 = translateModifierMask( static_cast<KeyModifierMask>(mask)); if (id2 != static_cast<KeyID>(id) || mask2 != static_cast<KeyModifierMask>(mask)) LOG((CLOG_DEBUG1 "key up translated to id=0x%08x, mask=0x%04x", id2, mask2)); // forward m_client->keyUp(id2, mask2, button); }
//-------------------------------------------------------------- // handle key press void mgWinServices::keyDown( WPARAM wParam, LPARAM lParam) { // set autorepeat flag int repeat = (lParam & (1 << 30)) != 0 ? MG_EVENT_KEYREPEAT : 0; // mgDebug("keydown %d repeat=%s", wParam, repeat?"true":"false"); if (wParam == VK_SHIFT) m_eventFlags |= MG_EVENT_SHIFT_DOWN; else if (wParam == VK_CONTROL) m_eventFlags |= MG_EVENT_CNTL_DOWN; else if (wParam == VK_MENU) m_eventFlags |= MG_EVENT_ALT_DOWN; // translate special keys int key = translateKey((int) wParam); if (m_theApp != NULL) { m_theApp->appKeyDown(key, m_eventFlags | repeat); } }
// 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); }
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; } } }
// 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; } } }
// 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; } } }
// 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; } } }
/** \brief The GUI's key release event handler. * * This function should be called from the SDL event loop. It takes a keyboard event * as an argument, translates it to PUI syntax and passes it to the * PUI-internal keyboard function. If there's no active widget which could * use the key event the function will return false, giving the caller * the opportunity to use the event for other purposes. * \param key A key symbol generated by an SDL keyboard event. * \return true if PUI was able to handle the event */ bool CGUIMain::keyUpEventHandler(SDL_keysym& key) { int tkey = translateKey(key); return puKeyboard(tkey, PU_UP); }
bool MMSInputLISThread::translateEvent(struct input_event *linux_evt, MMSInputEvent *inputevent) { static int x = -1, y = -1; static int px = 0, py = 0; static int pressed = 0xff; TRACEOUT("MMSINPUT", "EVENT TYPE = %d, CODE = %d, VALUE = %d", linux_evt->type, linux_evt->code, linux_evt->value); if(linux_evt->type == EV_ABS) { if(this->device.touch.swapXY) { if(linux_evt->code == ABS_X) { linux_evt->code = ABS_Y; } else if(linux_evt->code == ABS_Y) { linux_evt->code = ABS_X; } } switch(linux_evt->code) { case ABS_X: x = linux_evt->value - this->device.touch.rect.x; if(this->device.touch.swapX) { x = this->device.touch.rect.w - x; } x*= this->device.touch.xFactor; TRACEOUT("MMSINPUT", "EVENT TYPE = EV_ABS, CODE = ABS_X, X = %d, XF = %f", x, this->device.touch.xFactor); break; case ABS_Y: y = linux_evt->value - this->device.touch.rect.y; if(this->device.touch.swapY) { y = this->device.touch.rect.h - y; } y*= this->device.touch.yFactor; TRACEOUT("MMSINPUT", "EVENT TYPE = EV_ABS, CODE = ABS_Y, Y = %d, YF = %f", y, this->device.touch.yFactor); break; case ABS_PRESSURE: /* * if the touch driver doesn't send BTN_xxx events, use * ABS_PRESSURE as indicator for pressed/released */ TRACEOUT("MMSINPUT", "EVENT TYPE = EV_ABS, CODE = ABS_PRESSURE, VALUE = %d", linux_evt->value); if(!this->device.touch.haveBtnEvents) { pressed = (linux_evt->value ? 1 : 0); } break; default: break; } } else if(linux_evt->type == EV_KEY) { switch(linux_evt->code) { case BTN_LEFT: case BTN_TOUCH: pressed = (linux_evt->value ? 1 : 0); break; default: inputevent->key = translateKey(linux_evt->code); if (inputevent->key == MMSKEY_UNKNOWN) return false; inputevent->type = linux_evt->value ? MMSINPUTEVENTTYPE_KEYPRESS : MMSINPUTEVENTTYPE_KEYRELEASE; TRACEOUT("MMSINPUT", "KEY %s %d", (pressed ? "PRESS" : "RELEASE"), inputevent->key); return true; break; } } else if(linux_evt->type == EV_SYN) { if(pressed != 0xff) { inputevent->type = (pressed ? MMSINPUTEVENTTYPE_BUTTONPRESS : MMSINPUTEVENTTYPE_BUTTONRELEASE); if (pressed) { px = x; py = y; if (x<0 || y<0) { // x or y coordinate not set, ignore the PRESS event x = -1; y = -1; return false; } inputevent->posx = x; inputevent->posy = y; x = -1; y = -1; } else { if (x<0 || y<0) { // x or y coordinate not set, check pressed coordinate x = -1; y = -1; if (px<0 || py<0) { // px or py coordinate not set, ignore the RELEASE event return false; } else { inputevent->posx = px; inputevent->posy = py; } } else { inputevent->posx = x; inputevent->posy = y; x = -1; y = -1; } } TRACEOUT("MMSINPUT", "BUTTON %s at %dx%d", (pressed ? "PRESS" : "RELEASE"), inputevent->posx, inputevent->posy); pressed = 0xff; } else { inputevent->posx = x; inputevent->posy = y; inputevent->type = MMSINPUTEVENTTYPE_AXISMOTION; } return true; } return false; }