Example #1
0
/*
 * _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent
 * @device: a ClutterInputDevice
 * @stage: the stage the event should be delivered to
 * @xkb: XKB rules to translate the event
 * @_time: timestamp of the event
 * @key: a key code coming from a Linux input device
 * @state: TRUE if a press event, FALSE if a release event
 * @modifer_state: in/out
 *
 * Translate @key to a #ClutterKeyEvent using rules from xbbcommon.
 *
 * Return value: the new #ClutterEvent
 */
ClutterEvent *
_clutter_key_event_new_from_evdev (ClutterInputDevice *device,
				   ClutterInputDevice *core_device,
                                   ClutterStage       *stage,
                                   struct xkb_state   *xkb_state,
				   uint32_t            button_state,
                                   uint32_t            _time,
                                   xkb_keycode_t       key,
                                   uint32_t            state)
{
  ClutterEvent *event;
  xkb_keysym_t sym;
  const xkb_keysym_t *syms;
  char buffer[8];
  int n;

  if (state)
    event = clutter_event_new (CLUTTER_KEY_PRESS);
  else
    event = clutter_event_new (CLUTTER_KEY_RELEASE);

  /* We use a fixed offset of 8 because evdev starts KEY_* numbering from
   * 0, whereas X11's minimum keycode, for really stupid reasons, is 8.
   * So the evdev XKB rules are based on the keycodes all being shifted
   * upwards by 8. */
  key += 8;

  n = xkb_key_get_syms (xkb_state, key, &syms);
  if (n == 1)
    sym = syms[0];
  else
    sym = XKB_KEY_NoSymbol;

  event->key.device = core_device;
  event->key.stage = stage;
  event->key.time = _time;
  _clutter_xkb_translate_state (event, xkb_state, button_state);
  event->key.hardware_keycode = key;
  event->key.keyval = sym;
  clutter_event_set_source_device (event, device);

  n = xkb_keysym_to_utf8 (sym, buffer, sizeof (buffer));

  if (n == 0)
    {
      /* not printable */
      event->key.unicode_value = (gunichar) '\0';
    }
  else
    {
      event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
      if (event->key.unicode_value == -1 || event->key.unicode_value == -2)
        event->key.unicode_value = (gunichar) '\0';
    }

  return event;
}
Example #2
0
static int
test_utf8(xkb_keysym_t keysym, const char *expected)
{
    char s[8];
    int ret;

    ret = xkb_keysym_to_utf8(keysym, s, sizeof(s));
    if (ret <= 0)
        return ret;

    fprintf(stderr, "Expected keysym %#x -> %s (%u bytes)\n", keysym, expected,
            (unsigned) strlen(expected));
    fprintf(stderr, "Received keysym %#x -> %s (%u bytes)\n\n", keysym, s,
            (unsigned) strlen(s));

    return streq(s, expected);
}
Example #3
0
ushort TableGenerator::keysymToUtf8(quint32 sym)
{
    QByteArray chars;
    int bytes;
    chars.resize(8);
    bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
    if (bytes == -1)
        qWarning("TableGenerator::keysymToUtf8 - buffer too small");

    chars.resize(bytes-1);

#ifdef DEBUG_GENERATOR
    QTextCodec *codec = QTextCodec::codecForLocale();
    qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
                                                    .arg(codec->toUnicode(chars));
#endif
    return QString::fromUtf8(chars).at(0).unicode();
}
Example #4
0
void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event)
{
    const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);

    ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
    xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
    quint32 scan_code = mir_keyboard_event_scan_code(key_event);
    quint32 native_modifiers = mir_keyboard_event_modifiers(key_event);

    // Key modifier and unicode index mapping.
    auto modifiers = qt_modifiers_from_mir(native_modifiers);

    MirKeyboardAction action = mir_keyboard_event_action(key_event);
    QEvent::Type keyType = action == mir_keyboard_action_up
        ? QEvent::KeyRelease : QEvent::KeyPress;

    if (action == mir_keyboard_action_down)
        mLastInputWindow = window;

    QString text;
    QVarLengthArray<char, 32> chars(32);
    {
        int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size());

        if (result > 0) {
            text = QString::fromUtf8(chars.constData());
        }
    }
    int sym = translateKeysym(xk_sym, text);

    bool is_auto_rep = action == mir_keyboard_action_repeat;

    QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
    if (context) {
        QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
        qKeyEvent.setTimestamp(timestamp);
        if (context->filterEvent(&qKeyEvent)) {
            qCDebug(mirclient, "key event filtered out by input context");
            return;
        }
    }

    QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
}
Example #5
0
static int
gram_keysym_print (SCM keysym_smob, SCM port, scm_print_state * pstate)
{
  struct gram_keysym *keysym =
    (struct gram_keysym *) SCM_SMOB_DATA (keysym_smob);

  scm_puts ("#<keysym ", port);
  if (keysym->mods.mods & WLC_BIT_MOD_LOGO)
  {
    scm_puts ("S-", port);
  }
  if (keysym->mods.mods & WLC_BIT_MOD_CTRL)
  {
    scm_puts ("C-", port);
  }
  if (keysym->mods.mods & WLC_BIT_MOD_ALT)
  {
    scm_puts ("M-", port);
  }

  if(keysym->mouse) {
    scm_puts ("Mouse", port);
    scm_putc(keysym->mouse_button + '0', port);
  } else {
    char buf[64];
    xkb_keysym_to_utf8 (keysym->sym, buf, 64);

    if (buf[0] > 0 && buf[0] <= 0x7F)
    {
      xkb_keysym_get_name (keysym->sym, buf, 64);
    }

    SCM name = scm_from_utf8_string (buf);
    scm_display (name, port);
  }
  scm_puts (">", port);

  return 1;
}
Example #6
0
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;
    bool composed = false;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));

    if (xkb_compose_state && xkb_compose_state_feed(xkb_compose_state, ksym) == XKB_COMPOSE_FEED_ACCEPTED) {
        switch (xkb_compose_state_get_status(xkb_compose_state)) {
        case XKB_COMPOSE_NOTHING:
            break;
        case XKB_COMPOSE_COMPOSING:
            return;
        case XKB_COMPOSE_COMPOSED:
            /* xkb_compose_state_get_utf8 doesn't include the terminating byte in the return value
            * as xkb_keysym_to_utf8 does. Adding one makes the variable n consistent. */
            n = xkb_compose_state_get_utf8(xkb_compose_state, buffer, sizeof(buffer)) + 1;
            ksym = xkb_compose_state_get_one_sym(xkb_compose_state);
            composed = true;
            break;
        case XKB_COMPOSE_CANCELLED:
            xkb_compose_state_reset(xkb_compose_state);
            return;
        }
    }

    if (!composed) {
        n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));
    }

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        if (pam_state == STATE_PAM_WRONG)
            return;

        if (skip_without_validation()) {
            clear_input();
            return;
        }
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        skip_repeated_empty_password = true;
        return;
    default:
        skip_repeated_empty_password = false;
    }

    switch (ksym) {
    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
        * empty. */
        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password + input_position, buffer, n - 1);
    input_position += n - 1;
    DEBUG("current password = %.*s\n", input_position, password);

    if (unlock_indicator) {
        unlock_state = STATE_KEY_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;

        struct ev_timer *timeout = NULL;
        START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
        STOP_TIMER(clear_indicator_timeout);
    }

    START_TIMER(discard_passwd_timeout, TSTAMP_N_MINS(3), discard_passwd_cb);
}
Example #7
0
static void
simple_im_key_handler(struct simple_im *keyboard,
		      uint32_t serial, uint32_t time, uint32_t key, uint32_t sym,
		      enum wl_keyboard_key_state state)
{
	struct input_method_context *context = keyboard->context;
	char text[64];

	if (sym == XKB_KEY_Multi_key &&
	    state == WL_KEYBOARD_KEY_STATE_RELEASED &&
	    keyboard->compose_state == state_normal) {
		keyboard->compose_state = state_compose;
		memset(&keyboard->compose_seq, 0, sizeof(struct compose_seq));
		return;
	}

	if (keyboard->compose_state == state_compose) {
		uint32_t i = 0;
		struct compose_seq *cs;

		if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
			return;

		for (i = 0; i < sizeof(ignore_keys_on_compose) / sizeof(ignore_keys_on_compose[0]); i++) {
			if (sym == ignore_keys_on_compose[i]) {
				input_method_context_key(context, serial, time, key, state);
				return;
			}
		}

		for (i = 0; keyboard->compose_seq.keys[i] != 0; i++);

		keyboard->compose_seq.keys[i] = sym;

		cs = bsearch (&keyboard->compose_seq, compose_seqs,
			      sizeof(compose_seqs) / sizeof(compose_seqs[0]),
			      sizeof(compose_seqs[0]), compare_compose_keys);

		if (cs) {
			if (cs->keys[i + 1] == 0) {
				input_method_context_preedit_cursor(keyboard->context,
								    keyboard->serial,
								    0);
				input_method_context_preedit_string(keyboard->context,
								    keyboard->serial,
								    "", "");
				input_method_context_cursor_position(keyboard->context,
								     keyboard->serial,
								     0, 0);
				input_method_context_commit_string(keyboard->context,
								   keyboard->serial,
								   cs->text);
				keyboard->compose_state = state_normal;
			} else {
				uint32_t j = 0, idx = 0;

				for (; j <= i; j++) {
					idx += xkb_keysym_to_utf8(cs->keys[j], text + idx, sizeof(text) - idx);
				}

				input_method_context_preedit_cursor(keyboard->context,
								    keyboard->serial,
								    strlen(text));
				input_method_context_preedit_string(keyboard->context,
								    keyboard->serial,
								    text,
								    text);
			}
		} else {
			uint32_t j = 0, idx = 0;

			for (; j <= i; j++) {
				idx += xkb_keysym_to_utf8(keyboard->compose_seq.keys[j], text + idx, sizeof(text) - idx);
			}
			input_method_context_preedit_cursor(keyboard->context,
							    keyboard->serial,
							    0);
			input_method_context_preedit_string(keyboard->context,
							    keyboard->serial,
							    "", "");
			input_method_context_cursor_position(keyboard->context,
							     keyboard->serial,
							     0, 0);
			input_method_context_commit_string(keyboard->context,
							   keyboard->serial,
							   text);
			keyboard->compose_state = state_normal;
		}
		return;
	}

	if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0) {
		input_method_context_key(context, serial, time, key, state);
		return;
	}

	if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
		return;

	input_method_context_cursor_position(keyboard->context,
					     keyboard->serial,
					     0, 0);
	input_method_context_commit_string(keyboard->context,
					   keyboard->serial,
					   text);
}
Example #8
0
static void
key_handler(struct window *window,
	    struct input *input, uint32_t time,
	    uint32_t key, uint32_t sym, enum wl_keyboard_key_state state,
	    void *data)
{
	struct editor *editor = data;
	struct text_entry *entry;
	const char *new_char;
	char text[16];

	if (!editor->active_entry)
		return;

	entry = editor->active_entry;

	if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
		return;

	switch (sym) {
		case XKB_KEY_BackSpace:
			text_entry_commit_and_reset(entry);

			new_char = utf8_prev_char(entry->text, entry->text + entry->cursor);
			if (new_char != NULL)
				text_entry_delete_text(entry,
						       new_char - entry->text,
						       (entry->text + entry->cursor) - new_char);
			break;
		case XKB_KEY_Delete:
			text_entry_commit_and_reset(entry);

			new_char = utf8_next_char(entry->text + entry->cursor);
			if (new_char != NULL)
				text_entry_delete_text(entry,
						       entry->cursor,
						       new_char - (entry->text + entry->cursor));
			break;
		case XKB_KEY_Left:
			text_entry_commit_and_reset(entry);

			new_char = utf8_prev_char(entry->text, entry->text + entry->cursor);
			if (new_char != NULL) {
				entry->cursor = new_char - entry->text;
				entry->anchor = entry->cursor;
				widget_schedule_redraw(entry->widget);
			}
			break;
		case XKB_KEY_Right:
			text_entry_commit_and_reset(entry);

			new_char = utf8_next_char(entry->text + entry->cursor);
			if (new_char != NULL) {
				entry->cursor = new_char - entry->text;
				entry->anchor = entry->cursor;
				widget_schedule_redraw(entry->widget);
			}
			break;
		default:
			if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0)
				break;

			text_entry_commit_and_reset(entry);

			text_entry_insert_at_cursor(entry, text, 0, 0);
			break;
	}

	widget_schedule_redraw(entry->widget);
}
Example #9
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);
}
Example #10
0
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, "Control", XKB_STATE_MODS_DEPRESSED);
    xkb_state_update_key(xkb_state, event->detail, XKB_KEY_DOWN);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));
    n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        return;

    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
         * empty. */
        start_clear_indicator_timeout();
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password+input_position, buffer, n-1);
    input_position += n-1;
    DEBUG("current password = %.*s\n", input_position, password);

    unlock_state = STATE_KEY_ACTIVE;
    redraw_screen();
    unlock_state = STATE_KEY_PRESSED;

    struct ev_timer *timeout = calloc(sizeof(struct ev_timer), 1);
    if (timeout) {
        ev_timer_init(timeout, redraw_timeout, 0.25, 0.);
        ev_timer_start(main_loop, timeout);
    }

    stop_clear_indicator_timeout();
}
Example #11
0
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, "Control", XKB_STATE_MODS_DEPRESSED);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));
    n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        if (skip_without_validation()) {
            clear_input();
            return;
        }
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        skip_repeated_empty_password = true;
        return;
    default:
        skip_repeated_empty_password = false;
    }

    switch (ksym) {
    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
         * empty. */
        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password+input_position, buffer, n-1);
    input_position += n-1;
    DEBUG("current password = %.*s\n", input_position, password);

    unlock_state = STATE_KEY_ACTIVE;
    redraw_screen();
    unlock_state = STATE_KEY_PRESSED;

    struct ev_timer *timeout = NULL;
    START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
    STOP_TIMER(clear_indicator_timeout);
    START_TIMER(discard_passwd_timeout, TSTAMP_N_MINS(3), discard_passwd_cb);
}
Example #12
0
/*
 * This function will interpret a keyboard keysym, and call the
 * possible callbacks accordingly.
 */
void fghKeyboardInterpretKeysym(  SFG_Window* window,
                                  uint32_t key,
                                  xkb_keysym_t sym,
                                  uint32_t state )
{
    FGCBKeyboard keyboard_cb;
    FGCBSpecial special_cb;
    char string[16];
    int special = -1;

    /* GLUT API tells us to have two separate callbacks, one for
     * the ASCII translateable keypresses, and one for all the
     * others, which need to be translated to GLUT_KEY_Xs... */
    if( state )
    {
        keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
        special_cb  = (FGCBSpecial) ( FETCH_WCB( *window, Special  ));
    }
    else
    {
        keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
        special_cb  = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp  ));
    }

    switch( sym )
    {
    case XKB_KEY_F1:        special = GLUT_KEY_F1;        break;
    case XKB_KEY_F2:        special = GLUT_KEY_F2;        break;
    case XKB_KEY_F3:        special = GLUT_KEY_F3;        break;
    case XKB_KEY_F4:        special = GLUT_KEY_F4;        break;
    case XKB_KEY_F5:        special = GLUT_KEY_F5;        break;
    case XKB_KEY_F6:        special = GLUT_KEY_F6;        break;
    case XKB_KEY_F7:        special = GLUT_KEY_F7;        break;
    case XKB_KEY_F8:        special = GLUT_KEY_F8;        break;
    case XKB_KEY_F9:        special = GLUT_KEY_F9;        break;
    case XKB_KEY_F10:       special = GLUT_KEY_F10;       break;
    case XKB_KEY_F11:       special = GLUT_KEY_F11;       break;
    case XKB_KEY_F12:       special = GLUT_KEY_F12;       break;
    case XKB_KEY_Left:      special = GLUT_KEY_LEFT;      break;
    case XKB_KEY_Right:     special = GLUT_KEY_RIGHT;     break;
    case XKB_KEY_Up:        special = GLUT_KEY_UP;        break;
    case XKB_KEY_Down:      special = GLUT_KEY_DOWN;      break;
    case XKB_KEY_Page_Up:   special = GLUT_KEY_PAGE_UP;   break;
    case XKB_KEY_Page_Down: special = GLUT_KEY_PAGE_DOWN; break;
    case XKB_KEY_Home:      special = GLUT_KEY_HOME;      break;
    case XKB_KEY_End:       special = GLUT_KEY_END;       break;
    case XKB_KEY_Insert:    special = GLUT_KEY_INSERT;    break;
    case XKB_KEY_Num_Lock:  special = GLUT_KEY_NUM_LOCK;  break;
    case XKB_KEY_Begin:     special = GLUT_KEY_BEGIN;     break;
    case XKB_KEY_Delete:    special = GLUT_KEY_DELETE;    break;
    case XKB_KEY_Shift_L:   special = GLUT_KEY_SHIFT_L;   break;
    case XKB_KEY_Shift_R:   special = GLUT_KEY_SHIFT_R;   break;
    case XKB_KEY_Control_L: special = GLUT_KEY_CTRL_L;    break;
    case XKB_KEY_Control_R: special = GLUT_KEY_CTRL_R;    break;
    case XKB_KEY_Alt_L:     special = GLUT_KEY_ALT_L;     break;
    case XKB_KEY_Alt_R:     special = GLUT_KEY_ALT_R;     break;
    }

    if( special_cb && (special != -1) )
    {
        fgSetWindow( window );
        special_cb( special, window->State.MouseX, window->State.MouseY );
    }
    else if( keyboard_cb && (special == -1) )
    {
        fgSetWindow( window );
        xkb_keysym_to_utf8( sym, string, sizeof( string ) );
        keyboard_cb( string[0], window->State.MouseX, window->State.MouseY );
    }
}