Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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);
	}
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 6
0
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;
	}

}
Esempio n. 7
0
//
// 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);
	}
}
Esempio n. 8
0
	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;
		}
	}
Esempio n. 9
0
bool Util::checkKey(int16 &key) {
	Common::KeyState keyS;

	if (!getKeyFromBuffer(keyS))
		return false;

	key = translateKey(keyS);

	return true;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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));
}
Esempio n. 12
0
int16 Util::getKey() {
	Common::KeyState key;

	while (!getKeyFromBuffer(key)) {
		processInput();

		if (keyBufferEmpty())
			g_system->delayMillis(10 / _vm->_global->_speedFactor);
	}
	return translateKey(key);
}
Esempio n. 13
0
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();
}
Esempio n. 14
0
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);
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
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
}
Esempio n. 18
0
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);
		}
	}
}
Esempio n. 19
0
//--------------------------------------------------------------
// 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);
  }
}
Esempio n. 20
0
	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;
		}
	}
Esempio n. 21
0
/** \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;
}
Esempio n. 22
0
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);
}
Esempio n. 23
0
//--------------------------------------------------------------
// 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);
}
Esempio n. 25
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. 26
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. 27
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. 28
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. 29
0
/** \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);
}
Esempio n. 30
0
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;
}