예제 #1
0
XKB_EXPORT xkb_keysym_t
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
{
    const struct name_keysym *entry;
    char *tmp;
    xkb_keysym_t val;
    bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);

    if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
        return XKB_KEY_NoSymbol;

    entry = bsearch(s, name_to_keysym,
                    ARRAY_SIZE(name_to_keysym),
                    sizeof(*name_to_keysym),
                    compare_by_name);
    entry = find_sym(entry, s, icase);
    if (entry)
        return entry->keysym;

    if (*s == 'U' || (icase && *s == 'u')) {
        val = strtoul(&s[1], &tmp, 16);
        if (tmp && *tmp != '\0')
            return XKB_KEY_NoSymbol;

        if (val < 0x20 || (val > 0x7e && val < 0xa0))
            return XKB_KEY_NoSymbol;
        if (val < 0x100)
            return val;
        if (val > 0x10ffff)
            return XKB_KEY_NoSymbol;
        return val | 0x01000000;
    }
    else if (s[0] == '0' && (s[1] == 'x' || (icase && s[1] == 'X'))) {
        val = strtoul(&s[2], &tmp, 16);
        if (tmp && *tmp != '\0')
            return XKB_KEY_NoSymbol;

        return val;
    }

    /* Stupid inconsistency between the headers and XKeysymDB: the former has
     * no separating underscore, while some XF86* syms in the latter did.
     * As a last ditch effort, try without. */
    if (strncmp(s, "XF86_", 5) == 0 ||
        (icase && strncasecmp(s, "XF86_", 5) == 0)) {
        xkb_keysym_t ret;
        tmp = strdup(s);
        if (!tmp)
            return XKB_KEY_NoSymbol;
        memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
        ret = xkb_keysym_from_name(tmp, flags);
        free(tmp);
        return ret;
    }

    return XKB_KEY_NoSymbol;
}
예제 #2
0
static int
test_casestring(const char *string, xkb_keysym_t expected)
{
    xkb_keysym_t keysym;

    keysym = xkb_keysym_from_name(string, XKB_KEYSYM_CASE_INSENSITIVE);

    fprintf(stderr, "Expected casestring %s -> %x\n", string, expected);
    fprintf(stderr, "Received casestring %s -> %x\n\n", string, keysym);

    return keysym == expected;
}
예제 #3
0
static int
test_string(const char *string, xkb_keysym_t expected)
{
    xkb_keysym_t keysym;

    keysym = xkb_keysym_from_name(string, 0);

    fprintf(stderr, "Expected string %s -> %x\n", string, expected);
    fprintf(stderr, "Received string %s -> %x\n\n", string, keysym);

    return keysym == expected;
}
예제 #4
0
int uxkb_string_to_keysym(const char *n, uint32_t *out)
{
	uint32_t keysym;

	/* TODO: fix xkbcommon upstream to be case-insensitive if case-sensitive
	 * match fails. */
	keysym = xkb_keysym_from_name(n);
	if (!keysym)
		return -EFAULT;

	*out = keysym;
	return 0;
}
예제 #5
0
파일: keysym.c 프로젝트: emallson/gram
uint32_t gram_keysym_from_name(char* name) {
  uint32_t sym = xkb_keysym_from_name(name, XKB_KEYSYM_CASE_INSENSITIVE);

  static uint32_t symbols[GRAM_NUM_SYMS][2] = {{'.', XKB_KEY_period    },
                                               {'$', XKB_KEY_dollar    },
                                               {',', XKB_KEY_comma     },
                                               {'#', XKB_KEY_numbersign}};

  if(sym == XKB_KEY_NoSymbol && strlen(name) == 1) {
    /* check symbols */
    for(int i = 0; i < GRAM_NUM_SYMS; i++) {
      if(name[0] == symbols[i][0]) {
        return symbols[i][1];
      }
    }
  }
  return sym;
}
예제 #6
0
static xkb_keysym_t
cached_keysym_from_name(struct keysym_from_name_cache *cache,
                        const char *name, size_t len)
{
    xkb_keysym_t keysym;

    if (len >= sizeof(cache->cache[0].name))
        return XKB_KEY_NoSymbol;

    for (unsigned i = 0; i < KEYSYM_FROM_NAME_CACHE_SIZE; i++)
        if (cache->cache[i].len == len &&
            memcmp(cache->cache[i].name, name, len) == 0)
            return cache->cache[i].keysym;

    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
    strcpy(cache->cache[cache->next].name, name);
    cache->cache[cache->next].len = len;
    cache->cache[cache->next].keysym = keysym;
    cache->next = (cache->next + 1) % KEYSYM_FROM_NAME_CACHE_SIZE;
    return keysym;
}
예제 #7
0
static gboolean
accelerator_parse (const gchar         *accelerator,
                   MetaKeyCombo        *combo)
{
    guint keyval, keycode;
    MetaVirtualModifier mods;
    gint len;

    combo->keysym = 0;
    combo->keycode = 0;
    combo->modifiers = 0;

    if (accelerator == NULL)
        return FALSE;

    keyval = 0;
    keycode = 0;
    mods = 0;
    len = strlen (accelerator);
    while (len)
    {
        if (*accelerator == '<')
        {
            if (len >= 9 && is_primary (accelerator))
            {
                /* Primary is treated the same as Control */
                accelerator += 9;
                len -= 9;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 9 && is_control (accelerator))
            {
                accelerator += 9;
                len -= 9;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 7 && is_shift (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_SHIFT_MASK;
            }
            else if (len >= 6 && is_shft (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_SHIFT_MASK;
            }
            else if (len >= 6 && is_ctrl (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 6 && is_modx (accelerator))
            {
                static const guint mod_vals[] = {
                    META_VIRTUAL_ALT_MASK,
                    META_VIRTUAL_MOD2_MASK,
                    META_VIRTUAL_MOD3_MASK,
                    META_VIRTUAL_MOD4_MASK,
                    META_VIRTUAL_MOD5_MASK,
                };

                len -= 6;
                accelerator += 4;
                mods |= mod_vals[*accelerator - '1'];
                accelerator += 2;
            }
            else if (len >= 5 && is_ctl (accelerator))
            {
                accelerator += 5;
                len -= 5;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 5 && is_alt (accelerator))
            {
                accelerator += 5;
                len -= 5;
                mods |= META_VIRTUAL_ALT_MASK;
            }
            else if (len >= 6 && is_meta (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_META_MASK;
            }
            else if (len >= 7 && is_hyper (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_HYPER_MASK;
            }
            else if (len >= 7 && is_super (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_SUPER_MASK;
            }
            else
            {
                gchar last_ch;

                last_ch = *accelerator;
                while (last_ch && last_ch != '>')
                {
                    last_ch = *accelerator;
                    accelerator += 1;
                    len -= 1;
                }
            }
        }
        else
        {
            if (len >= 4 && is_keycode (accelerator))
            {
                keycode = strtoul (accelerator, NULL, 16);
                goto out;
            }
            else if (strcmp (accelerator, "Above_Tab") == 0)
            {
                keyval = META_KEY_ABOVE_TAB;
                goto out;
            }
            else
            {
                keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE);
                if (keyval == XKB_KEY_NoSymbol)
                {
                    char *with_xf86 = g_strconcat ("XF86", accelerator, NULL);
                    keyval = xkb_keysym_from_name (with_xf86, XKB_KEYSYM_CASE_INSENSITIVE);
                    g_free (with_xf86);

                    if (keyval == XKB_KEY_NoSymbol)
                        return FALSE;
                }
            }

            accelerator += len;
            len -= len;
        }
    }

out:
    combo->keysym = keyval;
    combo->keycode = keycode;
    combo->modifiers = mods;
    return TRUE;
}
예제 #8
0
int
main(void)
{
    assert(test_string("Undo", 0xFF65));
    assert(test_string("ThisKeyShouldNotExist", XKB_KEY_NoSymbol));
    assert(test_string("XF86_Switch_VT_5", 0x1008FE05));
    assert(test_string("VoidSymbol", 0xFFFFFF));
    assert(test_string("U4567", 0x1004567));
    assert(test_string("0x10203040", 0x10203040));
    assert(test_string("a", 0x61));
    assert(test_string("A", 0x41));
    assert(test_string("ch", 0xfea0));
    assert(test_string("Ch", 0xfea1));
    assert(test_string("CH", 0xfea2));
    assert(test_string("THORN", 0x00de));
    assert(test_string("Thorn", 0x00de));
    assert(test_string("thorn", 0x00fe));

    assert(test_keysym(0x1008FF56, "XF86Close"));
    assert(test_keysym(0x0, "NoSymbol"));
    assert(test_keysym(0x1008FE20, "XF86Ungrab"));
    assert(test_keysym(0x01001234, "U1234"));
    /* 16-bit unicode padded to width 4. */
    assert(test_keysym(0x010002DE, "U02DE"));
    /* 32-bit unicode padded to width 8. */
    assert(test_keysym(0x0101F4A9, "U0001F4A9"));

    assert(test_casestring("Undo", 0xFF65));
    assert(test_casestring("UNDO", 0xFF65));
    assert(test_casestring("A", 0x61));
    assert(test_casestring("a", 0x61));
    assert(test_casestring("ThisKeyShouldNotExist", XKB_KEY_NoSymbol));
    assert(test_casestring("XF86_Switch_vT_5", 0x1008FE05));
    assert(test_casestring("xF86_SwitcH_VT_5", 0x1008FE05));
    assert(test_casestring("xF86SwiTch_VT_5", 0x1008FE05));
    assert(test_casestring("xF86Switch_vt_5", 0x1008FE05));
    assert(test_casestring("VoidSymbol", 0xFFFFFF));
    assert(test_casestring("vOIDsymBol", 0xFFFFFF));
    assert(test_casestring("U4567", 0x1004567));
    assert(test_casestring("u4567", 0x1004567));
    assert(test_casestring("0x10203040", 0x10203040));
    assert(test_casestring("0X10203040", 0x10203040));
    assert(test_casestring("THORN", 0x00fe));
    assert(test_casestring("Thorn", 0x00fe));
    assert(test_casestring("thorn", 0x00fe));

    assert(test_utf8(XKB_KEY_y, "y"));
    assert(test_utf8(XKB_KEY_u, "u"));
    assert(test_utf8(XKB_KEY_m, "m"));
    assert(test_utf8(XKB_KEY_Cyrillic_em, "м"));
    assert(test_utf8(XKB_KEY_Cyrillic_u, "у"));
    assert(test_utf8(XKB_KEY_exclam, "!"));
    assert(test_utf8(XKB_KEY_oslash, "ø"));
    assert(test_utf8(XKB_KEY_hebrew_aleph, "א"));
    assert(test_utf8(XKB_KEY_Arabic_sheen, "ش"));

    assert(test_utf8(XKB_KEY_space, " "));
    assert(test_utf8(XKB_KEY_KP_Space, " "));
    assert(test_utf8(XKB_KEY_BackSpace, "\b"));
    assert(test_utf8(XKB_KEY_Escape, "\033"));
    assert(test_utf8(XKB_KEY_KP_Separator, ","));
    assert(test_utf8(XKB_KEY_KP_Decimal, "."));
    assert(test_utf8(XKB_KEY_Tab, "\t"));
    assert(test_utf8(XKB_KEY_KP_Tab, "\t"));
    assert(test_utf8(XKB_KEY_hyphen, "­"));
    assert(test_utf8(XKB_KEY_Linefeed, "\n"));
    assert(test_utf8(XKB_KEY_Return, "\r"));
    assert(test_utf8(XKB_KEY_KP_Enter, "\r"));
    assert(test_utf8(XKB_KEY_KP_Equal, "="));
    assert(test_utf8(XKB_KEY_9, "9"));
    assert(test_utf8(XKB_KEY_KP_9, "9"));
    assert(test_utf8(XKB_KEY_KP_Multiply, "*"));
    assert(test_utf8(XKB_KEY_KP_Subtract, "-"));

    assert(xkb_keysym_is_lower(XKB_KEY_a));
    assert(xkb_keysym_is_lower(XKB_KEY_Greek_lambda));
    assert(xkb_keysym_is_lower(xkb_keysym_from_name("U03b1", 0))); /* GREEK SMALL LETTER ALPHA */
    assert(xkb_keysym_is_lower(xkb_keysym_from_name("U03af", 0))); /* GREEK SMALL LETTER IOTA WITH TONOS */

    assert(xkb_keysym_is_upper(XKB_KEY_A));
    assert(xkb_keysym_is_upper(XKB_KEY_Greek_LAMBDA));
    assert(xkb_keysym_is_upper(xkb_keysym_from_name("U0391", 0))); /* GREEK CAPITAL LETTER ALPHA */
    assert(xkb_keysym_is_upper(xkb_keysym_from_name("U0388", 0))); /* GREEK CAPITAL LETTER EPSILON WITH TONOS */

    assert(!xkb_keysym_is_upper(XKB_KEY_a));
    assert(!xkb_keysym_is_lower(XKB_KEY_A));
    assert(!xkb_keysym_is_lower(XKB_KEY_Return));
    assert(!xkb_keysym_is_upper(XKB_KEY_Return));
    assert(!xkb_keysym_is_lower(XKB_KEY_hebrew_aleph));
    assert(!xkb_keysym_is_upper(XKB_KEY_hebrew_aleph));
    assert(!xkb_keysym_is_upper(xkb_keysym_from_name("U05D0", 0))); /* HEBREW LETTER ALEF */
    assert(!xkb_keysym_is_lower(xkb_keysym_from_name("U05D0", 0))); /* HEBREW LETTER ALEF */
    assert(!xkb_keysym_is_lower(XKB_KEY_8));
    assert(!xkb_keysym_is_upper(XKB_KEY_8));

    assert(xkb_keysym_is_keypad(XKB_KEY_KP_Enter));
    assert(xkb_keysym_is_keypad(XKB_KEY_KP_6));
    assert(xkb_keysym_is_keypad(XKB_KEY_KP_Add));
    assert(!xkb_keysym_is_keypad(XKB_KEY_Num_Lock));
    assert(!xkb_keysym_is_keypad(XKB_KEY_1));
    assert(!xkb_keysym_is_keypad(XKB_KEY_Return));

    assert(xkb_keysym_to_upper(XKB_KEY_a) == XKB_KEY_A);
    assert(xkb_keysym_to_upper(XKB_KEY_A) == XKB_KEY_A);
    assert(xkb_keysym_to_lower(XKB_KEY_a) == XKB_KEY_a);
    assert(xkb_keysym_to_lower(XKB_KEY_A) == XKB_KEY_a);
    assert(xkb_keysym_to_upper(XKB_KEY_Return) == XKB_KEY_Return);
    assert(xkb_keysym_to_lower(XKB_KEY_Return) == XKB_KEY_Return);
    assert(xkb_keysym_to_upper(XKB_KEY_Greek_lambda) == XKB_KEY_Greek_LAMBDA);
    assert(xkb_keysym_to_upper(XKB_KEY_Greek_LAMBDA) == XKB_KEY_Greek_LAMBDA);
    assert(xkb_keysym_to_lower(XKB_KEY_Greek_lambda) == XKB_KEY_Greek_lambda);
    assert(xkb_keysym_to_lower(XKB_KEY_Greek_LAMBDA) == XKB_KEY_Greek_lambda);
    assert(xkb_keysym_to_upper(XKB_KEY_eacute) == XKB_KEY_Eacute);
    assert(xkb_keysym_to_lower(XKB_KEY_Eacute) == XKB_KEY_eacute);

    return 0;
}
예제 #9
0
void TableGenerator::parseKeySequence(char *line)
{
    // we are interested in the lines with the following format:
    // <Multi_key> <numbersign> <S> : "♬"   U266c # BEAMED SIXTEENTH NOTE
    char *keysEnd = strchr(line, ':');
    if (!keysEnd)
        return;

    QComposeTableElement elem;
    // find the composed value - strings may be direct text encoded in the locale
    // for which the compose file is to be used, or an escaped octal or hexadecimal
    // character code. Octal codes are specified as "\123" and hexadecimal codes as "\0x123a".
    char *composeValue = strchr(keysEnd, '"');
    if (!composeValue)
        return;
    ++composeValue;

    char *composeValueEnd = strchr(composeValue, '"');
    if (!composeValueEnd)
        return;

    // if composed value is a quotation mark adjust the end pointer
    if (composeValueEnd[1] == '"')
        ++composeValueEnd;

    if (*composeValue == '\\' && composeValue[1] >= '0' && composeValue[1] <= '9') {
        // handle octal and hex code values
        char detectBase = composeValue[2];
        if (detectBase == 'x') {
            // hexadecimal character code
            elem.value = keysymToUtf8(fromBase16(composeValue + 3, composeValueEnd));
        } else {
            // octal character code
            elem.value = keysymToUtf8(fromBase8(composeValue + 1, composeValueEnd));
        }
    } else {
        // handle direct text encoded in the locale
        if (*composeValue == '\\')
            ++composeValue;
        elem.value = QString::fromLocal8Bit(composeValue, composeValueEnd - composeValue).at(0).unicode();
        ++composeValue;
    }

#ifdef DEBUG_GENERATOR
    // find the comment
    elem.comment = QString::fromLocal8Bit(composeValueEnd + 1).trimmed();
#endif

    // find the key sequence and convert to X11 keysym
    char *k = line;
    const char *kend = keysEnd;

    for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
        // find the next pair of angle brackets and get the contents within
        while (k < kend && *k != '<')
            ++k;
        char *sym = ++k;
        while (k < kend && *k != '>')
            ++k;
        *k = '\0';
        if (k < kend) {
            elem.keys[i] = xkb_keysym_from_name(sym, (xkb_keysym_flags)0);
            if (elem.keys[i] == XKB_KEY_NoSymbol) {
                if (!strcmp(sym, "dead_inverted_breve"))
                    elem.keys[i] = XKB_KEY_dead_invertedbreve;
                else if (!strcmp(sym, "dead_double_grave"))
                    elem.keys[i] = XKB_KEY_dead_doublegrave;
#ifdef DEBUG_GENERATOR
                else
                    qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym);
#endif
            }
        } else {
            elem.keys[i] = 0;
        }
    }
    m_composeTable.append(elem);
}
예제 #10
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);
}
예제 #11
0
파일: conf.c 프로젝트: keszybz/kmscon
int conf_parse_grab(struct conf_option *opt, bool on, const char *arg)
{
	char *buf, *tmp, *start;
	struct conf_grab grab, *gnew;

	memset(&grab, 0, sizeof(grab));

	buf = strdup(arg);
	if (!buf)
		return -ENOMEM;
	tmp = buf;

next_mod:
	if (*tmp == '<') {
		start = tmp;
		while (*tmp && *tmp != '>')
			++tmp;

		if (*tmp != '>') {
			log_error("missing '>' in grab '%s' near '%s'",
				  arg, start);
			goto err_free;
		}

		*tmp++ = 0;
		++start;
		if (!strcasecmp(start, "shift")) {
			grab.mods |= SHL_SHIFT_MASK;
		} else if (!strcasecmp(start, "lock")) {
			grab.mods |= SHL_LOCK_MASK;
		} else if (!strcasecmp(start, "control") ||
			   !strcasecmp(start, "ctrl")) {
			grab.mods |= SHL_CONTROL_MASK;
		} else if (!strcasecmp(start, "alt")) {
			grab.mods |= SHL_ALT_MASK;
		} else if (!strcasecmp(start, "logo")) {
			grab.mods |= SHL_LOGO_MASK;
		} else {
			log_error("invalid modifier '%s' in grab '%s'",
				  start, arg);
			goto err_free;
		}

		goto next_mod;
	}

	if (!*tmp) {
		log_error("missing key in grab '%s'", arg);
		goto err_free;
	}

	grab.keysym = xkb_keysym_from_name(tmp);
	if (!grab.keysym) {
		log_error("invalid key '%s' in grab '%s'", tmp, arg);
		goto err_free;
	}

	gnew = malloc(sizeof(*gnew));
	if (!gnew)
		goto err_free;
	memcpy(gnew, &grab, sizeof(*gnew));

	opt->type->free(opt);
	*(void**)opt->mem = gnew;
	free(buf);

	return 0;

err_free:
	free(buf);
	return -EFAULT;
}
예제 #12
0
// convert a Mod+key arg to mod mask and keysym
gboolean x11_parse_key ( char *combo, unsigned int *mod, xkb_keysym_t *key )
{
    GString      *str    = g_string_new ( "" );
    unsigned int modmask = 0;

    if ( strcasestr ( combo, "shift" ) ) {
        modmask |= x11_mod_masks[X11MOD_SHIFT];
        if ( x11_mod_masks[X11MOD_SHIFT] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Shift</b> key.\n" );
        }
    }
    if ( strcasestr ( combo, "control" ) ) {
        modmask |= x11_mod_masks[X11MOD_CONTROL];
        if ( x11_mod_masks[X11MOD_CONTROL] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Control</b> key.\n" );
        }
    }
    if ( strcasestr ( combo, "alt" ) ) {
        modmask |= x11_mod_masks[X11MOD_ALT];
        if ( x11_mod_masks[X11MOD_ALT] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Alt</b> key.\n" );
        }
    }
    if ( strcasestr ( combo, "super" ) ) {
        modmask |= x11_mod_masks[X11MOD_SUPER];
        if ( x11_mod_masks[X11MOD_SUPER] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Super</b> key.\n" );
        }
    }
    if ( strcasestr ( combo, "meta" ) ) {
        modmask |= x11_mod_masks[X11MOD_META];
        if ( x11_mod_masks[X11MOD_META] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Meta</b> key.\n" );
        }
    }
    if ( strcasestr ( combo, "hyper" ) ) {
        modmask |= x11_mod_masks[X11MOD_HYPER];
        if ( x11_mod_masks[X11MOD_HYPER] == 0 ) {
            g_string_append_printf ( str, "X11 configured keyboard has no <b>Hyper</b> key.\n" );
        }
    }
    int seen_mod = FALSE;
    if ( strcasestr ( combo, "Mod" ) ) {
        seen_mod = TRUE;
    }

    *mod = modmask;

    // Skip modifier (if exist) and parse key.
    char i = strlen ( combo );

    while ( i > 0 && !strchr ( "-+", combo[i - 1] ) ) {
        i--;
    }
    xkb_keysym_t sym = XKB_KEY_NoSymbol;
    if ( ( modmask & x11_mod_masks[X11MOD_SHIFT] ) != 0 ) {
        gchar * str = g_utf8_next_char ( combo + i );
        // If it is a single char, we make a capital out of it.
        if ( str != NULL && *str == '\0' ) {
            int      l = 0;
            char     buff[8];
            gunichar v = g_utf8_get_char ( combo + i );
            gunichar u = g_unichar_toupper ( v );
            if ( ( l = g_unichar_to_utf8 ( u, buff ) ) ) {
                buff[l] = '\0';
                sym     = xkb_keysym_from_name ( buff, XKB_KEYSYM_NO_FLAGS );
            }
        }
    }
    if ( sym == XKB_KEY_NoSymbol ) {
        sym = xkb_keysym_from_name ( combo + i, XKB_KEYSYM_CASE_INSENSITIVE );
    }

    if ( sym == XKB_KEY_NoSymbol || ( !modmask && ( strchr ( combo, '-' ) || strchr ( combo, '+' ) ) ) ) {
        g_string_append_printf ( str, "Sorry, rofi cannot understand the key combination: <i>%s</i>\n", combo );
        g_string_append ( str, "\nRofi supports the following modifiers:\n\t" );
        g_string_append ( str, "<i>Shift,Control,Alt,Super,Meta,Hyper</i>" );
        if ( seen_mod ) {
            g_string_append ( str, "\n\n<b>Mod1,Mod2,Mod3,Mod4,Mod5 are no longer supported, use one of the above.</b>" );
        }
    }
    if ( str->len > 0 ) {
        rofi_view_error_dialog ( str->str, TRUE );
        g_string_free ( str, TRUE );
        return FALSE;
    }
    g_string_free ( str, TRUE );
    *key = sym;
    return TRUE;
}