Esempio n. 1
0
File: nilwm.c Progetto: nqv/nilwm
/** Get KeySymbol from a KeyCode according to its state
 */
xcb_keysym_t get_keysym(xcb_keycode_t keycode, uint16_t state) {
    xcb_keysym_t k0, k1;

    /* Mode_Switch is ON */
    if (state & nil_.mask_modeswitch) {
        k0 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 2);
        k1 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 3);
    } else {
        k0 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 0);
        k1 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 1);
    }
    if (k1 == XCB_NO_SYMBOL) {
        k1 = k0;
    }
    /* NUM on and is from keypad */
    if ((state & nil_.mask_numlock) && xcb_is_keypad_key(k1)) {
        if ((state & XCB_MOD_MASK_SHIFT)
            || ((state & XCB_MOD_MASK_LOCK) && (state & nil_.mask_shiftlock))) {
            return k0;
        } else {
            return k1;
        }
    }
    if (!(state & XCB_MOD_MASK_SHIFT)) {
        if (!(state & XCB_MOD_MASK_LOCK)) {         /* SHIFT off, CAPS off */
            return k0;
        } else if (state & nil_.mask_capslock) {    /* SHIFT off, CAPS on */
            return k1;
        }
    } else {
        return k1;
    }
    NIL_ERR("no symbol: state=0x%x keycode=0x%x", state, keycode);
    return XCB_NO_SYMBOL;
}
Esempio n. 2
0
chord_t *make_chord(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool replay_event, bool lock_chain)
{
	chord_t *chord;
	if (button == XCB_NONE) {
		chord_t *prev = NULL;
		chord_t *orig = NULL;
		xcb_keycode_t *keycodes = keycodes_from_keysym(keysym);
		if (keycodes != NULL)
			for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++) {
				xcb_keysym_t natural_keysym = xcb_key_symbols_get_keysym(symbols, *kc, 0);
				for (unsigned char col = 0; col < KEYSYMS_PER_KEYCODE; col++) {
					xcb_keysym_t ks = xcb_key_symbols_get_keysym(symbols, *kc, col);
					if (ks == keysym) {
						uint16_t implicit_modfield = (col & 1 ? XCB_MOD_MASK_SHIFT : 0) | (col & 2 ? modfield_from_keysym(Mode_switch) : 0);
						uint16_t explicit_modfield = modfield | implicit_modfield;
						chord = malloc(sizeof(chord_t));
						bool unique = true;
						for (chord_t *c = orig; unique && c != NULL; c = c->more)
							if (c->modfield == explicit_modfield && c->keysym == natural_keysym)
								unique = false;
						if (!unique) {
							free(chord);
							break;
						}
						chord->keysym = natural_keysym;
						chord->button = button;
						chord->modfield = explicit_modfield;
						chord->next = chord->more = NULL;
						chord->event_type = event_type;
						chord->replay_event = replay_event;
						chord->lock_chain = lock_chain;
						if (prev != NULL)
							prev->more = chord;
						else
							orig = chord;
						prev = chord;
						PRINTF("key chord %u %u\n", natural_keysym, explicit_modfield);
						break;
					}
				}
			}
		free(keycodes);
		chord = orig;
	} else {
		chord = malloc(sizeof(chord_t));
		chord->keysym = keysym;
		chord->button = button;
		chord->modfield = modfield;
		chord->event_type = event_type;
		chord->replay_event = replay_event;
		chord->lock_chain = lock_chain;
		chord->next = chord->more = NULL;
		PRINTF("button chord %u %u\n", button, modfield);
	}
	return chord;
}
Esempio n. 3
0
xcb_keysym_t
xcb_key_release_lookup_keysym (xcb_key_symbols_t      *syms,
			   xcb_key_release_event_t *event,
			   int                 col)
{
  return xcb_key_symbols_get_keysym (syms, event->detail, col);
}
Esempio n. 4
0
/** The key press event handler.
 * \param ev The event.
 */
static void
event_handle_key(xcb_key_press_event_t *ev)
{
    lua_State *L = globalconf_get_lua_State();
    globalconf.timestamp = ev->time;

    if(globalconf.keygrabber != LUA_REFNIL)
    {
        if(keygrabber_handlekpress(L, ev))
        {
            lua_rawgeti(L, LUA_REGISTRYINDEX, globalconf.keygrabber);

            if(!luaA_dofunction(L, 3, 0))
            {
                warn("Stopping keygrabber.");
                luaA_keygrabber_stop(L);
            }
        }
    }
    else
    {
        /* get keysym ignoring all modifiers */
        xcb_keysym_t keysym = xcb_key_symbols_get_keysym(globalconf.keysyms, ev->detail, 0);
        client_t *c;
        if((c = client_getbywin(ev->event)) || (c = client_getbynofocuswin(ev->event)))
        {
            luaA_object_push(L, c);
            event_key_callback(ev, &c->keys, L, -1, 1, &keysym);
        }
        else
            event_key_callback(ev, &globalconf.keys, L, 0, 0, &keysym);
    }
}
Esempio n. 5
0
/** Handle keypress event.
 * \param L Lua stack to push the key pressed.
 * \param e Received XKeyEvent.
 * \return True if a key was successfully retrieved, false otherwise.
 */
bool
keygrabber_handlekpress(lua_State *L, xcb_key_press_event_t *e)
{
    /* convert keysym to string */
    char buf[MAX(MB_LEN_MAX, 32)];

    /* snprintf-like return value could be used here, but that should not be
     * necessary, as we have buffer big enough */
    xkb_state_key_get_utf8(globalconf.xkb_state, e->detail, buf, countof(buf) );

    if (is_control(buf))
    {
        /* Use text names for control characters, ignoring all modifiers. */
        xcb_keysym_t keysym = xcb_key_symbols_get_keysym(globalconf.keysyms,
                                                         e->detail, 0);
        xkb_keysym_get_name(keysym, buf, countof(buf));
    }

    luaA_pushmodifiers(L, e->state);
    lua_pushstring(L, buf);

    switch(e->response_type)
    {
      case XCB_KEY_PRESS:
        lua_pushliteral(L, "press");
        break;
      case XCB_KEY_RELEASE:
        lua_pushliteral(L, "release");
        break;
    }
    return true;
}
Esempio n. 6
0
xcb_keysym_t XcbIn::keysym(xcb_keycode_t code) const {
	xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(connection);
//	xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, kpe, kpe->state);
	xcb_keysym_t sym = xcb_key_symbols_get_keysym(symbols, code, 0);
	xcb_key_symbols_free(symbols);
	return sym;
}
Esempio n. 7
0
File: event.c Progetto: nqv/nilwm
static
void handle_key_press(xcb_key_press_event_t *e) {
    xcb_keysym_t sym;
    NIL_LOG("event: key press %d %d", e->state, e->detail);

    sym = xcb_key_symbols_get_keysym(nil_.key_syms, e->detail, 0);
    /* find key with *LOCK state removed */
    if (check_key(MOD_MASK_(e->state), sym)) {
        xcb_flush(nil_.con);
        return;
    }
}
Esempio n. 8
0
File: swm.c Progetto: JuliusP/swm
static xcb_keysym_t
xcb_get_keysym (xcb_keysym_t keycode) {
	xcb_key_symbols_t *keysyms;
	xcb_keysym_t keysym;

	if (!(keysyms = xcb_key_symbols_alloc(conn)))
		return 0;

	keysym = xcb_key_symbols_get_keysym(keysyms, (unsigned char)keycode, 0);
	xcb_key_symbols_free(keysyms);

	return keysym;
}
Esempio n. 9
0
void grab_chord(chord_t *chord)
{
	for (chord_t *c = chord; c != NULL; c = c->more) {
		if (c->button == XCB_NONE) {
			xcb_keycode_t *keycodes = keycodes_from_keysym(c->keysym);
			if (keycodes != NULL)
				for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++)
					if (c->keysym == xcb_key_symbols_get_keysym(symbols, *kc, 0))
						grab_key_button(*kc, c->button, c->modfield);
			free(keycodes);
		} else {
			grab_key_button(XCB_NONE, c->button, c->modfield);
		}
	}
}
Esempio n. 10
0
xcb_keysym_t keyboard::get_keysym( xcb_keycode_t code, uint16_t state )
{
	xcb_keysym_t k0, k1;

	if ( state & _modeswitch )
	{
		k0 = xcb_key_symbols_get_keysym( _keysyms, code, 2 );
		k1 = xcb_key_symbols_get_keysym( _keysyms, code, 3 );
	}
	else
	{
		k0 = xcb_key_symbols_get_keysym( _keysyms, code, 0 );
		k1 = xcb_key_symbols_get_keysym( _keysyms, code, 1 );
	}

	if ( k1 == XCB_NO_SYMBOL )
		k1 = k0;

	if ( ( state & _numlock ) && xcb_is_keypad_key( k1 ) )
	{
		if( ( state & XCB_MOD_MASK_SHIFT ) || (state & XCB_MOD_MASK_LOCK && ( state & _shiftlock ) ) )
			return k0;
		else
			return k1;
	}
	else if ( ! ( state & XCB_MOD_MASK_SHIFT ) && ! ( state & XCB_MOD_MASK_LOCK ) )
		return k0;
	else if ( ! ( state & XCB_MOD_MASK_SHIFT ) && ( state & XCB_MOD_MASK_LOCK && ( state & _capslock ) ) )
		return k1;
	else if ( ( state & XCB_MOD_MASK_SHIFT ) && ( state & XCB_MOD_MASK_LOCK && ( state & _capslock ) ) )
		return k1;
	else if ( ( state & XCB_MOD_MASK_SHIFT ) || ( state & XCB_MOD_MASK_LOCK && ( state & _shiftlock ) ) )
		return k1;

	return XCB_NO_SYMBOL;
}
Esempio n. 11
0
File: event.c Progetto: abresas/yawn
void event_keypress( xcb_generic_event_t* e ) {
    xcb_key_press_event_t * ev = (xcb_key_press_event_t*)e;
    timestamp = ev->time;
    xcb_keysym_t keysym = xcb_key_symbols_get_keysym( symbols, ev->detail, 0 );
    printf( "yawn: keypress %i %i %i\n", ev->detail, keysym, ev->state );
    int i = 0;
    printf( "keybinding count: %i\n", bindingsCount );
    for ( i = 0; i < bindingsCount; ++i ) {
        struct keybinding_t k = keybindings[ i ];
        printf( "key sym: %i state: %i\n", k.key, k.state );
        if ( k.key == keysym && ev->state & k.state ) {
            printf( "found key binding! calling callback! %i %s\n", k.argc, k.argv[ 0 ] );
            k.callback( k.argc, k.argv );
        }
    }
}
Esempio n. 12
0
/*
 * Returns true if sym is bound to any key except for 'except_keycode' on the
 * first four layers (normal, shift, mode_switch, mode_switch + shift).
 *
 */
static bool keysym_used_on_other_key(KeySym sym, xcb_keycode_t except_keycode) {
    xcb_keycode_t i,
                  min_keycode = xcb_get_setup(conn)->min_keycode,
                  max_keycode = xcb_get_setup(conn)->max_keycode;

    for (i = min_keycode; i && i <= max_keycode; i++) {
        if (i == except_keycode)
            continue;
        for (int level = 0; level < 4; level++) {
            if (xcb_key_symbols_get_keysym(keysyms, i, level) != sym)
                continue;
            return true;
        }
    }
    return false;
}
Esempio n. 13
0
xcb_keycode_t *
xcb_key_symbols_get_keycode(xcb_key_symbols_t *syms,
                            xcb_keysym_t      keysym)
{
  xcb_keysym_t ks;
  int j, nresult = 0;
  xcb_keycode_t i, min, max, *result = NULL, *result_np = NULL;

  if(syms && !xcb_connection_has_error(syms->c))
  {
      xcb_key_symbols_get_reply (syms, NULL);
      min = xcb_get_setup(syms->c)->min_keycode;
      max = xcb_get_setup(syms->c)->max_keycode;

      if (!syms->u.reply)
        return NULL;

      for(i = min; i && i <= max; i++)
          for(j = 0; j < syms->u.reply->keysyms_per_keycode; j++)
          {
              ks = xcb_key_symbols_get_keysym(syms, i, j);
              if(ks == keysym)
              {
                  nresult++;
                  result_np = realloc(result,
                                      sizeof(xcb_keycode_t) * (nresult + 1));

                  if(result_np == NULL)
                  {
                      free(result);
                      return NULL;
                  }

                  result = result_np;
                  result[nresult - 1] = i;
                  result[nresult] = XCB_NO_SYMBOL;
                  break;
              }
          }
  }
  
  return result;
}
Esempio n. 14
0
int handle_key_press_event(void *data, xcb_connection_t *c, xcb_key_press_event_t *event)
{
    xcb_keycode_t keycode = event->detail;
    xcb_keysym_t keysym = xcb_key_symbols_get_keysym(wm_conf.key_syms, keycode, 0);
    fprintf(stderr, "key press: keycode %u, keysym %u, state %u\n", keycode, keysym, event->state);
    /* search key bindings */
    SCM key_proc = SCM_UNDEFINED;
    keybinding_t *binding = keybinding_list;
    while (binding) {
        if (binding->keysym == keysym && binding->mod_mask == event->state) {
            key_proc = binding->scm_proc;
        }
        binding = binding->next;
    }

    if (key_proc != SCM_UNDEFINED)
        scm_call_0(key_proc);

    return 0;
}
Esempio n. 15
0
static int
_e_alert_handle_key_press(xcb_generic_event_t *event)
{
   xcb_key_symbols_t *symbols;
   xcb_key_press_event_t *ev;
   xcb_keysym_t key;
   int r = 0;

   ev = (xcb_key_press_event_t *)event;
   symbols = xcb_key_symbols_alloc(conn);
   key = xcb_key_symbols_get_keysym(symbols, ev->detail, 0);

   if (key == XK_F1)
     r = 1;
   else if (key == XK_F12)
     r = 2;

   xcb_key_symbols_free(symbols);

   return r;
}
Esempio n. 16
0
void WindowSelector::handleKeyPress(xcb_keycode_t keycode, uint16_t state)
{
    xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(connection());
    xcb_keysym_t kc = xcb_key_symbols_get_keysym(symbols, keycode, 0);
    int mx = 0;
    int my = 0;
    const bool returnPressed = (kc == XK_Return) || (kc == XK_space);
    const bool escapePressed = (kc == XK_Escape);
    if (kc == XK_Left) {
        mx = -10;
    }
    if (kc == XK_Right) {
        mx = 10;
    }
    if (kc == XK_Up) {
        my = -10;
    }
    if (kc == XK_Down) {
        my = 10;
    }
    if (state & XCB_MOD_MASK_CONTROL) {
        mx /= 10;
        my /= 10;
    }
    Cursor::setPos(Cursor::pos() + QPoint(mx, my));
    if (returnPressed) {
        selectWindowUnderPointer();
    }
    if (returnPressed || escapePressed) {
        if (escapePressed) {
            m_callback(nullptr);
        }
        release();
    }
    xcb_key_symbols_free(symbols);
}
Esempio n. 17
0
void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
{
    const uint8_t eventType = e->response_type & ~0x80;
    switch (eventType) {
    case XCB_BUTTON_PRESS:
    case XCB_BUTTON_RELEASE:
        handleButtonPress(reinterpret_cast<xcb_button_press_event_t*>(e));
        break;
    case XCB_MOTION_NOTIFY: {
            auto event = reinterpret_cast<xcb_motion_notify_event_t*>(e);
            auto it = std::find_if(m_windows.constBegin(), m_windows.constEnd(), [event] (const Output &o) { return o.window == event->event; });
            if (it == m_windows.constEnd()) {
                break;
            }
            pointerMotion(QPointF(event->root_x - (*it).xPosition.x() + (*it).internalPosition.x(),
                                  event->root_y - (*it).xPosition.y() + (*it).internalPosition.y()),
                          event->time);
        }
        break;
    case XCB_KEY_PRESS:
    case XCB_KEY_RELEASE: {
            auto event = reinterpret_cast<xcb_key_press_event_t*>(e);
            if (eventType == XCB_KEY_PRESS) {
                if (!m_keySymbols) {
                    m_keySymbols = xcb_key_symbols_alloc(m_connection);
                }
                const xcb_keysym_t kc = xcb_key_symbols_get_keysym(m_keySymbols, event->detail, 0);
                if (kc == XK_Control_R) {
                    grabKeyboard(event->time);
                }
                keyboardKeyPressed(event->detail - 8, event->time);
            } else {
                keyboardKeyReleased(event->detail - 8, event->time);
            }
        }
        break;
    case XCB_CONFIGURE_NOTIFY:
        updateSize(reinterpret_cast<xcb_configure_notify_event_t*>(e));
        break;
    case XCB_ENTER_NOTIFY: {
            auto event = reinterpret_cast<xcb_enter_notify_event_t*>(e);
            auto it = std::find_if(m_windows.constBegin(), m_windows.constEnd(), [event] (const Output &o) { return o.window == event->event; });
            if (it == m_windows.constEnd()) {
                break;
            }
            pointerMotion(QPointF(event->root_x - (*it).xPosition.x() + (*it).internalPosition.x(),
                                  event->root_y - (*it).xPosition.y() + (*it).internalPosition.y()),
                          event->time);
        }
        break;
    case XCB_CLIENT_MESSAGE:
        handleClientMessage(reinterpret_cast<xcb_client_message_event_t*>(e));
        break;
    case XCB_EXPOSE:
        handleExpose(reinterpret_cast<xcb_expose_event_t*>(e));
        break;
    case XCB_MAPPING_NOTIFY:
        if (m_keySymbols) {
            xcb_refresh_keyboard_mapping(m_keySymbols, reinterpret_cast<xcb_mapping_notify_event_t*>(e));
        }
        break;
    default:
        break;
    }
}
Esempio n. 18
0
/** Return the keysym from keycode.
 * \param detail The keycode received.
 * \param state The modifier state.
 * \return A keysym.
 */
xcb_keysym_t
keyresolv_get_keysym(xcb_keycode_t detail, uint16_t state)
{
    xcb_keysym_t k0, k1;

    /* 'col' (third parameter) is used to get the proper KeySym
     * according to modifier (XCB doesn't provide an equivalent to
     * XLookupString()).
     *
     * If Mode_Switch is ON we look into second group.
     */
    if(state & globalconf.modeswitchmask)
    {
        k0 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 4);
        k1 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 5);
    }
    else
    {
        k0 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 0);
        k1 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 1);
    }

    /* If the second column does not exists use the first one. */
    if(k1 == XCB_NO_SYMBOL)
        k1 = k0;

    /* The numlock modifier is on and the second KeySym is a keypad
     * KeySym */
    if((state & globalconf.numlockmask) && xcb_is_keypad_key(k1))
    {
        /* The Shift modifier is on, or if the Lock modifier is on and
         * is interpreted as ShiftLock, use the first KeySym */
        if((state & XCB_MOD_MASK_SHIFT)
           || (state & XCB_MOD_MASK_LOCK && (state & globalconf.shiftlockmask)))
            return k0;
        else
            return k1;
    }

    /* The Shift and Lock modifers are both off, use the first
     * KeySym */
    else if(!(state & XCB_MOD_MASK_SHIFT) && !(state & XCB_MOD_MASK_LOCK))
        return k0;

    /* The Shift modifier is off and the Lock modifier is on and is
     * interpreted as CapsLock */
    else if(!(state & XCB_MOD_MASK_SHIFT)
            && (state & XCB_MOD_MASK_LOCK && (state & globalconf.capslockmask)))
        /* The first Keysym is used but if that KeySym is lowercase
         * alphabetic, then the corresponding uppercase KeySym is used
         * instead */
        return k1;

    /* The Shift modifier is on, and the Lock modifier is on and is
     * interpreted as CapsLock */
    else if((state & XCB_MOD_MASK_SHIFT)
            && (state & XCB_MOD_MASK_LOCK && (state & globalconf.capslockmask)))
        /* The second Keysym is used but if that KeySym is lowercase
         * alphabetic, then the corresponding uppercase KeySym is used
         * instead */
        return k1;

    /* The Shift modifier is on, or the Lock modifier is on and is
     * interpreted as ShiftLock, or both */
    else if((state & XCB_MOD_MASK_SHIFT)
            || (state & XCB_MOD_MASK_LOCK && (state & globalconf.shiftlockmask)))
        return k1;

    return XCB_NO_SYMBOL;
}
Esempio n. 19
0
void ae3d::Window::PumpEvents()
{
    xcb_generic_event_t* event;
    
    while ((event = xcb_poll_for_event( WindowGlobal::connection )))
    {
        //const bool synthetic_event = (event->response_type & 0x80) != 0;
        const uint8_t response_type = event->response_type & ~0x80;

        switch (response_type)
        {
            case XCB_EVENT_MASK_BUTTON_PRESS:
            case XCB_EVENT_MASK_BUTTON_RELEASE:
            {
                const xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply( WindowGlobal::connection, xcb_query_pointer(WindowGlobal::connection, XDefaultRootWindow(WindowGlobal::display)), nullptr );
                const bool newb1 = (pointer->mask & XCB_BUTTON_MASK_1) != 0;
                const bool newb2 = (pointer->mask & XCB_BUTTON_MASK_2) != 0;
                const bool newb3 = (pointer->mask & XCB_BUTTON_MASK_3) != 0;
                const xcb_button_press_event_t* be = (xcb_button_press_event_t*)event;

                const auto b1Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse1Down : ae3d::WindowEventType::Mouse1Up;
                const auto b2Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse2Down : ae3d::WindowEventType::Mouse2Up;
                const auto b3Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::MouseMiddleDown : ae3d::WindowEventType::MouseMiddleUp;

                WindowGlobal::IncEventIndex();
                
                if (newb1)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type;
                }
                else if (newb3)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b2Type;
                }
                else if (newb2)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b3Type;
                }
                else
                {
                    std::cerr << "Unhandled mouse button." << std::endl;
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type;
                }
                
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = be->event_x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = be->event_y;
            }
            break;
            case XCB_KEY_PRESS:
            case XCB_KEY_RELEASE:
            {
                xcb_key_press_event_t *e = (xcb_key_press_event_t *)event;
                const bool isDown = (response_type == XCB_KEY_PRESS);
                const auto type = isDown ? ae3d::WindowEventType::KeyDown : ae3d::WindowEventType::KeyUp;

                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = type;
                const xcb_keysym_t keysym = xcb_key_symbols_get_keysym(WindowGlobal::key_symbols, e->detail, 0);
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].keyCode = WindowGlobal::keyMap[ keysym ];
            }
            case XCB_MOTION_NOTIFY:
            {
                xcb_motion_notify_event_t* e = (xcb_motion_notify_event_t*)event;
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = ae3d::WindowEventType::MouseMove;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = e->event_x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = e->event_y;
                break;
            }
            case XCB_CLIENT_MESSAGE:
            {
                xcb_client_message_event_t* client_message_event = (xcb_client_message_event_t*)event;
                if (client_message_event->type == WindowGlobal::wm_protocols)
                {
                    if (client_message_event->data.data32[0] == WindowGlobal::wm_delete_window)
                    {
                        exit(1);
                        break;
                    }
                 }
                break;
            }
            case XCB_EXPOSE:
            {
            }
            break;
        }
    }

    if (!WindowGlobal::gamePad.isActive)
    {
        return;
    }

    js_event j;

    while (read( WindowGlobal::gamePad.fd, &j, sizeof(js_event) ) == sizeof(js_event))
        //read(WindowGlobal::gamePad.fd, &j, sizeof(js_event));
    {
        // Don't care if init or afterwards
        j.type &= ~JS_EVENT_INIT;
            
        if (j.type == JS_EVENT_BUTTON)
        {
            if (j.number == WindowGlobal::gamePad.buttonA)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonA;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonB)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonB;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonX)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonX;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonY)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonY;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonStart)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonStart;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonBack)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonBack;
                }
            }
            else
            {
                //std::cout << "pressed button " << (int)j.number << std::endl;
            }
        }
        else if (j.type == JS_EVENT_AXIS)
        {
            if (j.number == WindowGlobal::gamePad.leftThumbX)
            {
                float x = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone );
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = WindowGlobal::lastLeftThumbY;
                WindowGlobal::lastLeftThumbX = x;
            }
            else if (j.number == WindowGlobal::gamePad.leftThumbY)
            {
                float y = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone );
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = WindowGlobal::lastLeftThumbX;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = y;
                WindowGlobal::lastLeftThumbY = y;
            }
            else if (j.number == WindowGlobal::gamePad.dpadXaxis)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadRight;
                }
                if (j.value < 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadLeft;
                }
            }
            else if (j.number == WindowGlobal::gamePad.dpadYaxis)
            {
                if (j.value < 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadUp;
                }
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadDown;
                }
            }
        }
    }
}
Esempio n. 20
0
void XCBInput::eventLoop() {
  xcb_keysym_t pressedKey;
  xcb_generic_event_t *event;
  xcb_motion_notify_event_t *motion;
  xcb_key_press_event_t *kp;
  xcb_key_release_event_t *kr;

  while ((event = xcb_poll_for_event(connection))) {
    switch (event->response_type & ~0x80) {
        case XCB_MOTION_NOTIFY:
            motion = reinterpret_cast<xcb_motion_notify_event_t *>(event);
            mediaLayer->mouseLook(motion->event_x, motion->event_y);
            break;

        case XCB_KEY_RELEASE:

            kr = reinterpret_cast<xcb_key_release_event_t *>(event);
            pressedKey = xcb_key_symbols_get_keysym(syms, kr->detail, 0);
            pressedKeys.removeAll(pressedKey);

            switch (pressedKey) {
            case XK_Shift_L:
              inputSpeed = .01;
                          break;

            }
            break;

        case XCB_KEY_PRESS:
            kp = reinterpret_cast<xcb_key_press_event_t *>(event);
            pressedKey = xcb_key_symbols_get_keysym(syms, kp->detail, 0);

            switch (pressedKey) {
                case XK_Escape:
                    emit shutdown();
                    break;
                case XK_m:
                  mediaLayer->toggleMouseGrab();
                    break;
                case XK_f:
                  mediaLayer->toggleFullScreen();
                    break;
                case XK_p:
                    RenderEngine::Instance().toggleFBO();
                    break;
                case XK_c:
                    RenderEngine::Instance().toggleLightView();
                    break;
                case XK_Tab:
                    RenderEngine::Instance().toggleWire();
                    break;
                case XK_Shift_L:
                    inputSpeed = .1;
                	break;
                	
                default:
                    pressedKeys.push_back(pressedKey);
            }
            break;

        default:
            /* Unknown event type, ignore it */
            // printf ("Unknown event: %d\n", event->response_type);
            break;
    }

      free(event);
  }

  foreach(xcb_keysym_t key, pressedKeys) {
      checkKey(key);
    }
Esempio n. 21
0
internal void
hhxcb_process_events(hhxcb_context *context, hhxcb_state *state, game_input *new_input, game_input *old_input)
{
    game_controller_input *old_keyboard_controller = GetController(old_input, 0);
    game_controller_input *new_keyboard_controller = GetController(new_input, 0);
    *new_keyboard_controller = {};
    new_keyboard_controller->IsConnected = true;
    for (
            uint button_index = 0;
            button_index < ArrayCount(new_keyboard_controller->Buttons);
            ++button_index)
    {
        new_keyboard_controller->Buttons[button_index].EndedDown =
            old_keyboard_controller->Buttons[button_index].EndedDown;
    }

    new_input->MouseX = old_input->MouseX;
    new_input->MouseY = old_input->MouseY;

    for (int i = 0; i < HHXCB_MAX_CONTROLLERS; ++i)
    {
        hhxcb_controller_info *pad = &context->controller_info[i];
        if (!pad->is_active)
        {
            continue;
        }
        game_controller_input *old_controller = GetController(old_input, i+1);
        game_controller_input *new_controller = GetController(new_input, i+1);

        *new_controller = *old_controller;
        new_controller->IsConnected = true;
        new_controller->IsAnalog = old_controller->IsAnalog;

        js_event j;
        while (read(pad->fd, &j, sizeof(js_event)) == sizeof(js_event))
        {
            // Don't care if init or afterwards
            j.type &= ~JS_EVENT_INIT;
            if (j.type == JS_EVENT_BUTTON)
            {
                if (j.number == pad->a_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->ActionDown,
                            &new_controller->ActionDown);
                }
                else if (j.number == pad->b_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->ActionRight,
                            &new_controller->ActionRight);
                }
                else if (j.number == pad->x_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->ActionLeft,
                            &new_controller->ActionLeft);
                }
                else if (j.number == pad->y_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->ActionUp,
                            &new_controller->ActionUp);
                }
                else if (j.number == pad->l1_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->LeftShoulder,
                            &new_controller->LeftShoulder);
                }
                else if (j.number == pad->r1_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->RightShoulder,
                            &new_controller->RightShoulder);
                }
                else if (j.number == pad->back_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->Back,
                            &new_controller->Back);
                }
                else if (j.number == pad->start_button)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->Start,
                            &new_controller->Start);
                }
                else
                {
                    printf("Unhandled button: number %d, value %d\n",
                            j.number, j.value);
                }
            }
            if (j.type == JS_EVENT_AXIS)
            {
                uint16 dead_zone = pad->axis_dead_zones[j.number];
                bool axis_inverted = pad->axis_inverted[j.number];
                if (j.number == pad->left_thumb_x_axis)
                {
                    new_controller->StickAverageX =
                        hhxcb_process_controller_axis(j.value, dead_zone,
                                axis_inverted);
                    if (new_controller->StickAverageX != 0.0f)
                    {
                        new_controller->IsAnalog = true;
                    }
                }
                else if (j.number == pad->left_thumb_y_axis)
                {
                    new_controller->StickAverageY =
                        hhxcb_process_controller_axis(j.value, dead_zone,
                                axis_inverted);
                    if (new_controller->StickAverageY != 0.0f)
                    {
                        new_controller->IsAnalog = true;
                    }
                }
                else if (j.number == pad->right_thumb_x_axis)
                {
                    // TODO(nbm): Do something with this.  Here otherwise we get spammed.
                }
                else if (j.number == pad->right_thumb_y_axis)
                {
                    // TODO(nbm): Do something with this.  Here otherwise we get spammed.
                }
                else if (j.number == pad->dpad_x_axis)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->MoveRight,
                            &new_controller->MoveRight);
                    hhxcb_process_button((j.value < 0),
                            &old_controller->MoveLeft,
                            &new_controller->MoveLeft);
                    new_controller->IsAnalog = false;
                }
                else if (j.number == pad->dpad_y_axis)
                {
                    hhxcb_process_button((j.value > 0),
                            &old_controller->MoveDown,
                            &new_controller->MoveDown);
                    hhxcb_process_button((j.value < 0),
                            &old_controller->MoveUp,
                            &new_controller->MoveUp);
                    new_controller->IsAnalog = false;
                }
                else
                {
                    printf("Unhandled Axis: number %d, value %d\n",
                        j.number, j.value);
                }

            }
        }
        if (errno != EAGAIN) {
            context->need_controller_refresh = true;
        }
    }

    xcb_generic_event_t *event;
    while ((event = xcb_poll_for_event(context->connection)))
    {
        // NOTE(nbm): The high-order bit of response_type is whether the event
        // is synthetic.  I'm not sure I care, but let's grab it in case.
        bool32 synthetic_event = (event->response_type & 0x80) != 0;
        uint8_t response_type = event->response_type & ~0x80;
        switch(response_type)
        {
            case XCB_KEY_PRESS:
            case XCB_KEY_RELEASE:
            {
                xcb_key_press_event_t *e = (xcb_key_press_event_t *)event;
                bool32 is_down = (response_type == XCB_KEY_PRESS);
                xcb_keysym_t keysym = xcb_key_symbols_get_keysym(context->key_symbols, e->detail, 0);

                if (keysym == XK_w)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->MoveUp, is_down);
                }
                else if (keysym == XK_a)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->MoveLeft, is_down);
                }
                else if (keysym == XK_s)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->MoveDown, is_down);
                }
                else if (keysym == XK_d)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->MoveRight, is_down);
                }
                else if (keysym == XK_q)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->LeftShoulder, is_down);
                }
                else if (keysym == XK_e)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->RightShoulder, is_down);
                }
                else if (keysym == XK_Up)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->ActionUp, is_down);
                }
                else if (keysym == XK_Left)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->ActionLeft, is_down);
                }
                else if (keysym == XK_Down)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->ActionDown, is_down);
                }
                else if (keysym == XK_Right)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->ActionRight, is_down);
                }
                else if (keysym == XK_Escape)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->Back, is_down);
                }
                else if (keysym == XK_space)
                {
                    hhxcb_process_keyboard_message(&new_keyboard_controller->Start, is_down);
                }
                else if (keysym == XK_l)
                {
                    if (is_down)
                    {
                        if (state->playback_index == 0)
                        {
                            if (state->recording_index == 0)
                            {
                                hhxcb_start_recording(state, 1);
                            }
                            else
                            {
                                hhxcb_stop_recording(state);
                                hhxcb_start_playback(state, 1);
                            }
                        }
                        else
                        {
                            hhxcb_stop_playback(state);
                        }
                    }
                }
                break;
            }
            case XCB_NO_EXPOSURE:
            {
                // No idea what these are, but they're spamming me.
                break;
            }
            case XCB_MOTION_NOTIFY:
            {
                xcb_motion_notify_event_t* e = (xcb_motion_notify_event_t*)event;
                new_input->MouseX = e->event_x;
                new_input->MouseY = e->event_y;
                break;
            }
            case XCB_CLIENT_MESSAGE:
            {
                xcb_client_message_event_t* client_message_event = (xcb_client_message_event_t*)event;

                if (client_message_event->type == context->wm_protocols)
                {
                    if (client_message_event->data.data32[0] == context->wm_delete_window)
                    {
                        context->ending_flag = 1;
                        break;
                    }
                }
                break;
            }
            default:
            {
                break;
            }
        }
        free(event);
    };
}
Esempio n. 22
0
static void
ephyrProcessKeyRelease(xcb_generic_event_t *xev)
{
    xcb_connection_t *conn = hostx_get_xcbconn();
    xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
    static xcb_key_symbols_t *keysyms;
    static int grabbed_screen = -1;
    int mod1_down = ephyrUpdateGrabModifierState(key->state);

    if (!keysyms)
        keysyms = xcb_key_symbols_alloc(conn);

    if (!EphyrWantNoHostGrab &&
        (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L
          || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R)
         && (key->state & XCB_MOD_MASK_CONTROL)) ||
        ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L
          || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R)
         && (key->state & XCB_MOD_MASK_SHIFT)))) {
        KdScreenInfo *screen = screen_from_window(key->event);
        EphyrScrPriv *scrpriv = screen->driver;

        if (grabbed_screen != -1) {
            xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME);
            xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
            grabbed_screen = -1;
            hostx_set_win_title(screen,
                                "(ctrl+shift grabs mouse and keyboard)");
        }
        else if (!mod1_down) {
            /* Attempt grab */
            xcb_grab_keyboard_cookie_t kbgrabc =
                xcb_grab_keyboard(conn,
                                  TRUE,
                                  scrpriv->win,
                                  XCB_TIME_CURRENT_TIME,
                                  XCB_GRAB_MODE_ASYNC,
                                  XCB_GRAB_MODE_ASYNC);
            xcb_grab_keyboard_reply_t *kbgrabr;
            xcb_grab_pointer_cookie_t pgrabc =
                xcb_grab_pointer(conn,
                                 TRUE,
                                 scrpriv->win,
                                 0,
                                 XCB_GRAB_MODE_ASYNC,
                                 XCB_GRAB_MODE_ASYNC,
                                 scrpriv->win,
                                 XCB_NONE,
                                 XCB_TIME_CURRENT_TIME);
            xcb_grab_pointer_reply_t *pgrabr;
            kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL);
            if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) {
                xcb_discard_reply(conn, pgrabc.sequence);
                xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
            } else {
                pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL);
                if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS)
                    {
                        xcb_ungrab_keyboard(conn,
                                            XCB_TIME_CURRENT_TIME);
                    } else {
                    grabbed_screen = scrpriv->mynum;
                    hostx_set_win_title
                        (screen,
                         "(ctrl+shift releases mouse and keyboard)");
                }
            }
        }
    }

    if (!ephyrKbd ||
        !((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
        return;
    }

    /* Still send the release event even if above has happened server
     * will get confused with just an up event.  Maybe it would be
     * better to just block shift+ctrls getting to kdrive all
     * together.
     */
    ephyrUpdateModifierState(key->state);
    KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE);
}
Esempio n. 23
0
void fill_keycodes() {

	struct xkb_keymap *keymap;
	struct xkb_context *context;
	const struct xkb_rule_names rules={
		.rules=xkb_names[0],
		.model=xkb_names[1],
		.layout=xkb_names[2],
		.variant=xkb_names[3],
		.options=xkb_names[4]
	};
	struct xkb_state *state;
	enum xkb_state_component current_state;
	int counter;
	int i,j,k;
	char mods[256];
	char keysym_asc[256];
	char file_path[256];
	char command[15];
	uint32_t max_keys;
	int w,h,retval;
	int jumpto;

	context=xkb_context_new(0);
	keymap=xkb_keymap_new_from_names(context,&rules,0);

	state=NULL;

	// Get all the modifier keys
	for(i=8;i<256;i++) {
		state=xkb_state_new(keymap);
		current_state=xkb_state_update_key(state, i,XKB_KEY_DOWN);
		if (current_state!=0) {
			mods[i]=1;
		} else {
			mods[i]=0;
		}
		xkb_state_unref(state);
	}
	mods[7]=1; // fake mod, used for "no mod"

	// Read the keyboard definition files

	sprintf(file_path,"%s/%s.keymap",BASE_CONFIG_DIR,lang_onscreen);

	FILE *keyboard_file=fopen(file_path,"r");
	if (keyboard_file==NULL) {
		printf("Can't open keyboard definition file %s. Trying with US file\n",file_path);
		sprintf(file_path,"%s/us.keymap",BASE_CONFIG_DIR);
		keyboard_file=fopen(file_path,"r");
		if (keyboard_file==NULL) {
			printf("Also failed to open the US keymap file. Aborting.\n");
			exit(-1);
		}
	}
	retval=fscanf(keyboard_file,"%s %d",command,&keyboard_blocks);
	if (retval!=2) {
		printf("Can't read the number of blocks\n");
	} else {
		max_keys=keyboard_blocks*4*KEYS_PER_ROW;
		keyboard_lowercase=(struct key_element *)malloc(max_keys*sizeof(struct key_element));
		memset(keyboard_lowercase,0,max_keys*sizeof(struct key_element));
		for(counter=0;(!feof(keyboard_file))&&(counter<max_keys);counter++) {
			retval=fscanf(keyboard_file,"%s %d %d",command,&w,&h);
			if(retval!=3) {
				break;
			}
			keyboard_lowercase[counter].size=KEYS_FONT_SIZE;
			keyboard_lowercase[counter].g_element[0]=0;
			keyboard_lowercase[counter].w=w;
			keyboard_lowercase[counter].h=h;
			keyboard_lowercase[counter].keycode=0;
			keyboard_lowercase[counter].modifier=0;
			if (!strcmp(command,"BLANK")) {
				keyboard_lowercase[counter].type=KEY_BLANK;
				keyboard_lowercase[counter].keysym=0;
			} else if (!strcmp(command,"KEY")) {
				keyboard_lowercase[counter].type=KEY_PH;
				retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element);
				keyboard_lowercase[counter].keysym=init_utf8_to_keysym(keyboard_lowercase[counter].g_element);
				if (keyboard_lowercase[counter].keysym==0) {
					keyboard_lowercase[counter].type=KEY_BLANK;
				}
			} else if ((!strcmp(command,"KEYSYM"))||(!strcmp(command,"KEYSYMTEXT"))) {
				keyboard_lowercase[counter].type=KEY_PH;
				retval=fscanf(keyboard_file,"%s",keysym_asc);
				keyboard_lowercase[counter].keysym=xkb_keysym_from_name(keysym_asc,0);
				if (keyboard_lowercase[counter].keysym==0) {
					printf("Unknown keysym %s\n",keysym_asc);
					keyboard_lowercase[counter].type=KEY_BLANK;
				} else {
					if (!strcmp(command,"KEYSYMTEXT")) {
						retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element);
						keyboard_lowercase[counter].size=KEYS_TEXT_FONT_SIZE;
					} else {
						retval=xkb_keysym_to_utf8(keyboard_lowercase[counter].keysym,keyboard_lowercase[counter].g_element,7);
						if (retval==-1) {
							retval++;
						}
						keyboard_lowercase[counter].g_element[retval]=0;// terminate string
					}
				}
			} else if (!strcmp(command,"TAB")) {
				keyboard_lowercase[counter].type=KEY_TAB;
				keyboard_lowercase[counter].keysym=XK_Tab;
			} else if (!strcmp(command,"SPACE")) {
				keyboard_lowercase[counter].type=KEY_SPACE;
				keyboard_lowercase[counter].keysym=XK_space;
			} else if (!strcmp(command,"RETURN")) {
				keyboard_lowercase[counter].type=KEY_RETURN;
				keyboard_lowercase[counter].keysym=XK_Return;
			} else if (!strcmp(command,"DELETE")) {
				keyboard_lowercase[counter].type=KEY_DELETE;
				keyboard_lowercase[counter].keysym=XK_BackSpace;
			} else if (!strcmp(command,"JUMPTO")) {
				retval=fscanf(keyboard_file,"%d %s",&jumpto,command);
				keyboard_lowercase[counter].type=KEY_JUMPTO;
				keyboard_lowercase[counter].keycode=jumpto;
				keyboard_lowercase[counter].keysym=0;
				if (!strcmp(command,"GEN")) {
					keyboard_lowercase[counter].modifier=0;
				} else if (!strcmp(command,"SHIFT")) {
					keyboard_lowercase[counter].modifier=1;
				} else if (!strcmp(command,"SYMBOLS")) {
					keyboard_lowercase[counter].modifier=2;
				} else if (!strcmp(command,"LETTERS")) {
					keyboard_lowercase[counter].modifier=3;
				}
				if (jumpto>=keyboard_blocks) {
					printf("Ilegal jump to block %d (max. is %d)\n",jumpto,keyboard_blocks);
					keyboard_lowercase[counter].type=KEY_BLANK;
				}
			} else if (!strcmp(command,"UP")) {
				keyboard_lowercase[counter].type=KEY_UP;
				keyboard_lowercase[counter].keysym=XK_Up;
			} else if (!strcmp(command,"DOWN")) {
				keyboard_lowercase[counter].type=KEY_DOWN;
				keyboard_lowercase[counter].keysym=XK_Down;
			} else if (!strcmp(command,"LEFT")) {
				keyboard_lowercase[counter].type=KEY_LEFT;
				keyboard_lowercase[counter].keysym=XK_Left;
			} else if (!strcmp(command,"RIGHT")) {
				keyboard_lowercase[counter].type=KEY_RIGHT;
				keyboard_lowercase[counter].keysym=XK_Right;
			} else {
				printf("Unknown command %s\n",command);
				keyboard_lowercase[counter].type=KEY_BLANK;
				keyboard_lowercase[counter].keysym=0;
			}
		}

		xkb_keysym_t  keysym;
		xkb_keycode_t keycode_mod;
		for(i=7;i<256;i++) { // do a loop on every modifier
			if (!mods[i]) {
				continue; // In this loop we test each modifier with each keycode
			}
			state=xkb_state_new(keymap);
			if (i!=7) {
				xkb_state_update_key(state, i,XKB_KEY_DOWN); // press the modifier key
				keycode_mod=i;
			} else {
				keycode_mod=0;
			}
			for(j=8;j<256;j++) {
				if (mods[j]) {
					continue;  // Don't test modifiers; we want "normal" keys
				}
				keysym=xkb_state_key_get_one_sym(state, j);
				if (keysym==XKB_KEY_NoSymbol) {
					continue;
				}
				for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained
					if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].keysym==keysym)) {
						keyboard_lowercase[k].keycode=j;
						keyboard_lowercase[k].modifier=keycode_mod;
					}
				}
			}
			xkb_state_unref(state);
		}
		/*for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained
			printf("Texto: %s, Keysym: %d, mod: %d\n",keyboard_lowercase[k].g_element,keyboard_lowercase[k].keycode,keyboard_lowercase[k].modifier);
		}*/

		// Now assign new keysyms to keycodes not used, to allow other keysyms not available in US keyboards

		xcb_key_symbols_t *symbols;

		symbols=xcb_key_symbols_alloc(conn);
		xcb_flush(conn);

		xcb_keycode_t keycode=8;
		xcb_keycode_t keycode_found;

		xcb_keysym_t keysyms[4];
		xcb_keycode_t keycode_shift;

		struct lower_upper_t {xcb_keysym_t upper_first;
				xcb_keysym_t upper_last;
				xcb_keysym_t lower_first;
				xcb_keysym_t lower_last;
			};

		struct lower_upper_t lower_upper[] = {
				{XKB_KEY_Agrave,XKB_KEY_Odiaeresis,XKB_KEY_agrave,XKB_KEY_odiaeresis},
				{XKB_KEY_Oslash,XKB_KEY_THORN,XKB_KEY_oslash,XKB_KEY_thorn},
				{0,0,0,0}
			};
		struct lower_upper_t *iter_lu;

		keycode_shift=*xcb_key_symbols_get_keycode(symbols,XKB_KEY_Shift_L);
		for(k=0;k<max_keys;k++) { // and now we check each desired key with the keysymbol obtained
			if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].type!=KEY_JUMPTO)) {
				// this key is not available in US keyboards; let's redefine a keycode for it
				keycode_found=0;
				while(keycode<256) {
					if ((0==xcb_key_symbols_get_keysym(symbols,keycode,0))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,1))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,2))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,3))) {
							keycode_found=keycode;
							break;
					}
					keycode++;
				}

				if (keycode_found==0) {
					printf("No more codes available\n");
					break; // there are no more free keycodes available
				}
				keycode=keycode_found;
				keysyms[0]=keyboard_lowercase[k].keysym;
				keysyms[1]=0;
				keysyms[2]=keyboard_lowercase[k].keysym;
				keysyms[3]=0;
				for(iter_lu=lower_upper;iter_lu->upper_first;iter_lu++) {
					if ((keysyms[0]>=iter_lu->upper_first)&&(keysyms[0]<=iter_lu->upper_last)) { // it's an uppercase special character
						keysyms[0]|=0x20; // first character as lowercase
						break;
					}
					if ((keysyms[0]>=iter_lu->lower_first)&&(keysyms[0]<=iter_lu->lower_last)) { // it's a lowercase special character
						keysyms[2]&=0xDF; // second character as uppercase
						break;
					}
				}
				xcb_change_keyboard_mapping(conn,1,keycode,4,keysyms); // insert the new keysym
				for(j=k;j<max_keys;j++) { // set the keycode and the shift modifier, if needed, to all keys with that keysyms
					if (keyboard_lowercase[j].keysym==keysyms[0]) {
						keyboard_lowercase[j].keycode=keycode;
						keyboard_lowercase[j].modifier=0;
						continue;
					}
					if (keyboard_lowercase[j].keysym==keysyms[2]) {
						keyboard_lowercase[j].keycode=keycode;
						keyboard_lowercase[j].modifier=keycode_shift;
						continue;
					}
				}
				keycode++;
			}
		}
		xcb_key_symbols_free(symbols);
	}

	fclose(keyboard_file);
	keyboard_current_block=0;
	xkb_keymap_unref(keymap);
	xkb_context_unref(context);
}