summaryrefslogtreecommitdiff
path: root/src/state.c
Commit message (Collapse)AuthorAgeFilesLines
* API to query modifier set required to type a keysymJaroslaw Kubik2020-03-201-11/+0
| | | | | | | | | The new API is useful to implement features like auto-type and desktop automation. Since the inputs for these features is usually specified in terms of the symbols that need to be typed, the implementation needs to be able to invert the keycode->keysym transformation and produce a sequence of keycodes that can be used to type the requested character(s).
* build: include config.h manuallyRan Benita2019-12-271-0/+2
| | | | | | | | | Previously we included it with an `-include` compiler directive. But that's not portable. And it's better to be explicit anyway. Every .c file should have `include "config.h"` first thing. Signed-off-by: Ran Benita <ran@unusedvar.com>
* Use bitwise test instead of popcount to check if one bit is setMichael Forney2019-06-101-1/+1
| | | | | | | | | | | We don't need to determine the total number of bits set to determine if exactly one is set. Additionally, on x86_64 without any -march=* flag, __builtin_popcount will get compiled to a function call to the compiler runtime (on gcc), or a long sequence of bit operations (on clang). Signed-off-by: Michael Forney <mforney@mforney.org>
* Convert http:// -> https:// where possibleRan Benita2017-12-211-2/+2
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* state: cure boolean blindness in the filter functions' resultRan Benita2017-04-271-24/+41
| | | | | | Makes it a little easier to understand the filters. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: remove unneeded NULL checkRan Benita2017-04-271-3/+0
| | | | | | xkb_filter_new() cannot return NULL. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: reorder new() functions before the set() functions in the codeRan Benita2017-04-271-28/+28
| | | | | | So that they may be read more naturally in chronological order. Signed-off-by: Ran Benita <ran234@gmail.com>
* utils: rename popcount to avoid conflict in NetBSDRan Benita2016-11-141-1/+1
| | | | | Resolves https://github.com/xkbcommon/libxkbcommon/issues/41 Signed-off-by: Ran Benita <ran234@gmail.com>
* state: add GTK consumed modifiers modeRan Benita2016-10-311-0/+25
| | | | | | | | | | | | | | | | This is more or less what is implemented here: https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkkeys-x11.c?h=3.19.10#n1131 The implementation here is more technically correct but should provide the same results. Try it out with ./test/interactive-evdev -g (modifiers prefixed with "-" are consumed). https://bugzilla.gnome.org/show_bug.cgi?id=754110 https://github.com/xkbcommon/libxkbcommon/issues/17 Signed-off-by: Ran Benita <ran234@gmail.com>
* state: allow different modes for calculating consumed modifiersRan Benita2016-10-311-36/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The current functions dealing with consumed modifiers use the traditional XKB definition of consumed modifiers (see description in the added documentation). However, for several users of the library (e.g. GTK) this definition is unsuitable or too eager. This is exacerbated by some less-than-ideal xkeyboard-config type definitions (CTRL+ALT seems to cause most grief...). So, because we - want to enable alternative interpretations, but - don't want to expose too much internal details, and - want to keep things simple for all library users, we add a high-level "mode" parameter which selects the desired interpretation. New ones can be added as long as they make some sense. All of the old consumed-modifiers functions keep using the traditional ("XKB") mode. I mark xkb_state_mod_mask_remove_consumed() and as deprecated without adding a *2 variant because I don't it is very useful (or used) in practice. Alternative modes are added in subsequent commits (this commit only adds a mode for the existing behavior). https://github.com/xkbcommon/libxkbcommon/issues/17 Signed-off-by: Ran Benita <ran234@gmail.com>
* src/state: match_mod_masks can return bool instead of intRan Benita2016-06-091-6/+4
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* state: factor out get_entry_for_mods()Ran Benita2016-02-281-7/+11
| | | | | | Will be useful later. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: factor out entry_is_active() checkRan Benita2016-02-281-11/+14
| | | | | | | Makes the code slightly cleaner and I plan to use the function in another place. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: reduce scope of fake actionRan Benita2015-09-071-4/+4
| | | | | | Also rename to "dummy" as I think it is a nicer name. Signed-off-by: Ran Benita <ran234@gmail.com>
* Reduce variable scopesRan Benita2014-10-231-3/+2
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* state: correctly infer inactive type entriesRan Benita2014-10-171-1/+1
| | | | | | | | | | | | | | | | | | | | | The current test is incorrect, since 'map[None]' is entirely valid. In most cases this doesn't cause any problems, since the default fallback is Level1, and it's almost always 'map[None] = Level1' anyway. But in one case in xkeyboard-config it isn't, in types/numpad(mac): type "KEYPAD" { modifiers = None; map[None] = Level2; level_name[Level2] = "Number"; }; So before checking if no modifiers were mapped, make sure there *were* any modifiers at all. https://bugs.freedesktop.org/show_bug.cgi?id=85092 Reported-by: Gatis Paeglis <gatis.paeglis@digia.com> Signed-off-by: Ran Benita <ran234@gmail.com>
* state: make sure the mods are fully resolved after xkb_state_update_mask()Ran Benita2014-08-181-0/+21
| | | | | | | | | | | | Virtual modifiers can have "mappings" to real modifiers, e.g. NumLock may also set Mod2. In a normal turn of events, the various components (depressed, latched, locked, and consequently effective) include the mapped mods, because the masks are pre-resolved everywhere. However, xkb_state_update_mask() accepts arbitrary mod masks, which may not be resolved (if it comes from somewhere other than xkb_state_serialize_mods()). So let's always resolve them ourselves. Signed-off-by: Ran Benita <ran234@gmail.com>
* Make the effective mod mask calculation available to other filesRan Benita2014-08-181-0/+22
| | | | | | We will want to use that function in state.c as well. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: no need for loop in xkb_state_update_mask()Ran Benita2014-08-181-16/+7
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* keymap, keycodes, compat: don't use darray for LEDsRan Benita2014-04-221-3/+3
| | | | | | Use a static array of size XKB_MAX_LEDS instead, as in xkb_mod_set. Signed-off-by: Ran Benita <ran234@gmail.com>
* keymap: rename wrap_group_into_range -> XkbWrapGroupIntoRangeRan Benita2014-04-191-4/+4
| | | | | | It better fits with the naming convention in keymap.h. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: fix consumed modifier calculationRan Benita2014-03-271-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The current calculation is in short: entry ? (entry->mask & ~entry->preserve) : 0 This changes it be type->mask & ~(entry ? entry->preserve : 0) This is what Xlib does. While less intuitive, it is actually more correct, if you follow this deduction: - The key group's type->mask defines which modifiers the key even cares about. The others are completely irrelevant (and in fact they are masked out from all sided in the level calculation). Example: NumLock for an alphabetic key. - The type->mask, the mods which are not masked out, are *all* relevant (and in fact in the level calculation they must match *exactly* to the state). These mods affect which level is chosen for the key, whether they are active or not. - Because the type->mask mods are all relevant, they must be considered as consumed by the calculation *even if they are not active*. Therefore we use type->mask instead of entry->mask. The second change is what happens when no entry is found: return 0 or just take preserve to be 0? Let's consider an example, the basic type type "ALPHABETIC" { modifiers = Shift+Lock; map[Shift] = Level2; map[Lock] = Level2; level_name[Level1] = "Base"; level_name[Level2] = "Caps"; }; Suppose Shift+Lock is active - it doesn't match any entry, thus it gets to level 0. The first interpretation would take them both to be unconsumed, the second (new one) would take them both to be consumed. This seems much better: Caps is active, and Shift disables it, they both do something. This change also fixes a pretty lousy bug (since 0.3.2), where Shift appears to apparently *not* disable Caps. What actually happens is that Caps is not consumed (see above) but active, thus the implicit capitalization in get_one_sym() kicks in and capitalizes it anyway. Reported-by: Davinder Pal Singh Bhamra Signed-off-by: Ran Benita <ran234@gmail.com>
* state: apply control transformation on utf8/utf32 keysym stringsRan Benita2014-03-221-11/+110
| | | | | | | | | | | This is required by the specification: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier and clients expect this to happen. https://bugs.freedesktop.org/show_bug.cgi?id=75892 Reported-by: Gatis Paeglis <gatis.paeglis@digia.com> Signed-off-by: Ran Benita <ran234@gmail.com>
* state: add xkb_state_key_get_{utf8,utf32}() API functionsRan Benita2014-03-221-0/+65
| | | | | | | | | | | | | | | | | | | | | | | | These functions generally have the same effect as xkb_state_key_get_syms() + xkb_keysym_to_utf{8,32}(). So why add them? - They provide a slightly nicer interface, especially if the string is the only interest. - It makes the handling of multiple-keysyms-to-utf8 transparent. For the designated use-case of multiple-keysyms (unicode combining characters), this is a must. We also validate the UTF-8, which the user might not otherwise do. - We will need to apply some transformation on the resulting string which depend on the xkb_state. This is not possible with the xkb_keysym_* functions. With these functions, the existing xkb_keysym_to_utf{8,32}() are not expected to be used by a typical user; they are "raw" functions. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: Add xkb_state_key_get_consumed_modsJasper St. Pierre2014-02-221-0/+11
| | | | | | | This retrieves the mask of consumed modifiers for a given key and state, which is helpful for toolkits without having them to do it one modifier at a time, or pass in 0xFFFFFFFF to xkb_state_remove_consumed_mods to "reverse-engineer" the consumed mods.
* state: check wrap_group_into_range() return valueRan Benita2014-02-091-8/+12
| | | | | | | | It returns XKB_LAYOUT_INVALID in case num_groups == 0. So we shouldn't just save it in the state. Note, though, that this condition is generally impossible. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: optimize xkb_state_led_update_all()Ran Benita2014-02-081-21/+33
| | | | | | | | | | | | | | Before: ran@ran:~/src/libxkbcommon$ ./test/bench-key-proc ran 20000000 iterations in 6.623018074s After: ran@ran:~/src/libxkbcommon$ ./test/bench-key-proc ran 20000000 iterations in 4.762291091s Not that anyone needs to process millions of keys per second... Signed-off-by: Ran Benita <ran234@gmail.com>
* Use (1u << idx) instead of (1 << idx) where appropriateRan Benita2014-02-081-13/+13
| | | | | | | | It doesn't matter (I think), since the implicit conversion doesn't have any effect (e.g. sign-extension). But it's better to be aware of the type. Signed-off-by: Ran Benita <ran234@gmail.com>
* Fix sign-compare warningsRan Benita2014-02-081-6/+5
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* state: use the XKB_MOD_MASK constantRan Benita2014-02-071-1/+1
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* Fix some cppcheck warningsRan Benita2014-01-111-2/+1
| | | | | | | | | | | | | | | | | | | | | | | Someone was nice enough to run this for us: ftp://ftp.sunet.se/pub/Linux/distributions/Debian/debian/pool/main/libx/libxkbcommon/libxkbcommon_0.3.1.orig.tar.gz [libxkbcommon-0.3.1/src/keymap.c:86]: (style) The scope of the variable 'j' can be reduced. [libxkbcommon-0.3.1/src/keymap.c:87]: (style) The scope of the variable 'key' can be reduced. [libxkbcommon-0.3.1/src/keysym-utf.c:843]: (style) The scope of the variable 'mid' can be reduced. [libxkbcommon-0.3.1/src/state.c:992]: (style) The scope of the variable 'str' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/action.c:467]: (style) The scope of the variable 'absolute' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/rules.c:468]: (style) The scope of the variable 'consumed' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/rules.c:862]: (style) The scope of the variable 'mlvo' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/rules.c:863]: (style) The scope of the variable 'kccgst' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/rules.c:865]: (style) The scope of the variable 'match_type' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/symbols.c:753]: (style) The scope of the variable 'toAct' can be reduced. [libxkbcommon-0.3.1/src/xkbcomp/symbols.c:1573]: (style) The scope of the variable 'key' can be reduced. [libxkbcommon-0.3.1/test/common.c:80]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'. [libxkbcommon-0.3.1/test/interactive.c:358]: (style) The scope of the variable 'nevs' can be reduced. [libxkbcommon-0.3.1/test/interactive.c:236]: (style) Checking if unsigned variable 'nsyms' is less than zero. [libxkbcommon-0.3.1/test/interactive.c:226]: (style) Unused variable: unicode Signed-off-by: Ran Benita <ran234@gmail.com>
* state: apply capitalization transformation on keysymsRan Benita2013-08-151-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The xkbproto spec says: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier If the Lock modifier is not consumed by the symbol lookup process, routines that determine the symbol and string that correspond to an event should capitalize the result. This was not an issue until now, because most xkeyboard-config keymaps do not utilize this "feature", and specify the keysyms for the Lock modifier explicitly instead. However, some keymaps do depend on it, e.g. ch(fr) for eacute and others. The spec goes on to describe two options for doing this transformation: locale-sensitive and locale-insensitive. We opt for the latter; it is less desirable but we don't want *that* headache. Also, only xkb_state_key_get_one_sym() is changed; xkb_state_key_get_syms() is left as-is, and always reports the untransformed keysyms. This is for the following reasons: - The API doesn't allow it, since we return a const pointer directly to the keymap keysyms table and we can't transform that. - The transformation doesn't make sense for multiple-keysyms. - It can be useful for an application to get the "raw" keysyms if it wants to (e.g. maybe it wants to do the transformation itself). Finally, note that xkb_state_mod_index_is_consumed() does *not* report Lock as consumed even if it was used in the transformation. This is what Xlib does. This definitely doesn't fall under the "hard to misuse" API rule but it's the best we can do. https://bugs.freedesktop.org/show_bug.cgi?id=67167 Reported-By: Gatis Paeglis <gatis.paeglis@digia.com> Signed-off-by: Ran Benita <ran234@gmail.com>
* keymap: remove struct xkb_key_redirect_actionRan Benita2013-07-311-1/+0
| | | | | | | | | | The file src/xkbcomp/action.c already doesn't handle this action type and fails if it encounters it. So lets not pretend to do something with it, and ignore it rather than failing. If we/someone wants this we can consider implementing it. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: use stdbool in filtersRan Benita2013-03-181-32/+32
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* keymap: rename xkb_kt_map_entry to xkb_key_type_entryRan Benita2013-03-181-6/+6
| | | | | | | That's a better name and fits more nicely. Also change type->map to type->entries. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: small style fixRan Benita2013-03-181-11/+13
| | | | Signed-off-by: Ran Benita <ran234@gmail.com>
* Change 'indicator' to 'led' everywhere possibleRan Benita2013-03-181-19/+19
| | | | | | | | | | | | | | | | | | The code currently uses the two names interchangeably. Settle on 'led', because it is shorter, more recognizable, and what we use in our API (though of course the parser still uses 'indicator'). In camel case we make it 'Led'. We change 'xkb_indicator_map' to just 'xkb_led' and the variables of this type are 'led'. This mimics 'xkb_key' and 'key'. IndicatorNameInfo and LEDInfo are changed to 'LedNameInfo' and 'LedInfo', and the variables are 'ledi' (like 'keyi' etc.). This is instead of 'ii' and 'im'. This might make a few places a bit confusing, but less than before I think. It's also shorter. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: fix unbound virtual modifier bugRan Benita2013-03-181-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Recent xkeyboard-config introduced the following line in symbols/level3: vmods = LevelThree, However, the XKM format which xkbcomp produces for the X server can't handle explicit virtual modifiers such as this: https://bugs.freedesktop.org/show_bug.cgi?id=4927 So by doing the following, for example: setxkbmap -layout de (or another 3-level layouts) xkbcomp $DISPLAY out.xkb xkbcomp out.xkb $DISPLAY The modifier is lost and can't be used for switching to Level3 (see the included test). We, however, are affected worse by this bug when we load the out.xkb keymap. First, the FOUR_LEVEL_ALPHABETIC key type has these entries: map[None] = Level1; map[Shift] = Level2; map[Lock] = Level2; map[LevelThree] = Level3; [...] Now, because the LevelThree virtual modifier is not bound to anything, the effective mask of the "map[LevelThree]" entry is just 0. So when the modifier state is empty (initial state), this entry is chosen, and we get Level3, instead of failing to match any entry and getting the default Level1. The difference in behavior from the xserver stems from this commit: acdad6058d52dc8a3e724dc95448300850d474f2 Which removed the entry->active field. Without bugs, this would be correct; however, it seems in this case we should just follow the server's behavior. The server sets the entry->active field like so in XKBMisc.c: /* entry is active if vmods are bound */ entry->active = (mask != 0); The xkblib spec explains this field, but does not specify how to initialize it. This commit does the same as above but more directly. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: rename state->cur to state->componentsRan Benita2012-11-111-68/+70
| | | | | | | 'cur' doesn't make sense anymore. 'components' is a bit long for this, but not too bad, and nothing better comes to mind. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: don't keep the previous state components in xkb_stateRan Benita2012-11-111-7/+9
| | | | | | | | There is really no need to keep this in the struct, we can just allocate it on the stack when we need to. Don't know why I did it this way. Signed-off-by: Ran Benita <ran234@gmail.com>
* keymap: wrap the layout parameter if it is out of range for the keyRan Benita2012-11-111-1/+1
| | | | | | | | | | | | | | | | | | | | | The functions num_levels_for_key() and get_syms_by_level() have a 'layout' parameter. Currently it is expected that this value is always legal for the key, as determined by num_layouts_for_key(). However, there are legitimate use cases for passing an out-of-range layout there, most probably passing the effective layout, and expecting to get the keysyms/levels for just this layout. So we wrap it just as we do in the xkb_state_* functions. This is also useful for stuff like this: http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-lookup-key If this behavior is not desired, the user has the option to check against num_layouts_for_key herself. https://bugs.freedesktop.org/show_bug.cgi?id=56866 Reported-by: Gatis Paeglis <gatis.paeglis@digia.com> Signed-off-by: Ran Benita <ran234@gmail.com>
* state, context: allow passing NULL to *_unref()Ran Benita2012-10-291-1/+1
| | | | | | | | | | For error handling code, it's nice to be able to pass NULL to these function without worrying about segfaults ensuing. free() sets the precedent here. Also document this fact. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: don't use xkb_keymap_num_layouts internallyRan Benita2012-10-261-5/+3
| | | | | | Clearer and more greppable this way. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: don't use xkb_state_serialize_* internallyRan Benita2012-10-261-9/+3
| | | | | | The code in these cases is clearer when done directly. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: fix possible index-out-of-bounds in action dispatch tableRan Benita2012-10-241-0/+11
| | | | | | | | | | | | | The current code assumes that action->type always falls in the range of the xkb_action_type enum. But keymaps can also have Private actions, which are allowed to set their own type number. So with a default xkeyboard-config keymap, keycode 86 at level 4, which triggers such an action, causes us to crash. Fix it by always checking the bounds. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: fix typo in state component copyingRan Benita2012-10-231-1/+1
| | | | | | Gladly no-one should have been fast enough to hit this. Signed-off-by: Ran Benita <ran234@gmail.com>
* Report which components of the state have changedRan Benita2012-10-221-4/+45
| | | | | | | | | | | | | | | | | | | | | | We add a return value to the xkb_state_update_key and xkb_state_update_mask, which reports to the caller which of the state components have changed as a result. This restores the XKB functionality of the XkbStateNotify and XkbIndicatorsStateNotify events. See: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Events It is quite useful in some situations. For example, it allows an application to avoid doing some work if nothing of relevance in the state has changed. Say, a keyboard layout applet. Also useful for debugging. The deltas themselves are not provided, because I can't see a use case. If needed, it should be possible to add some API for that. In xkbcommon, keymaps are immutable, so all of the other *Notify events from XKB are irrelevant. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: add struct state_componentsRan Benita2012-10-221-68/+72
| | | | | | | | This holds all of the state component fields in the state in one struct. We will later want to keep the previous state components after updates, so this will allow us to do it without duplicating the fields. Signed-off-by: Ran Benita <ran234@gmail.com>
* Split the mods, layout, leds parts of xkb_state_componentsRan Benita2012-10-221-23/+25
| | | | | | | | | | | | | | | | | Note first: This commits breaks the ABI somewhat. If an application is run against this commit without recompiling against the updated header, these break: - xkb_state_layout_*_is_active always retuns false. - xkb_state_serialize_mods always returns 0. So it might break layout switching in some applications. However, xkbcommon-compat.h provides the necessary fixes, so recompiling should work (though updating the application is even better). Split the enum to its individual components, which enables us to refer to them individually. We will use that later for reporting which components of the state have changed after update. Signed-off-by: Ran Benita <ran234@gmail.com>
* state: make mod_index_is_consumed() return -1 on invalid inputRan Benita2012-10-131-2/+2
| | | | | | Like all the other functions. Signed-off-by: Ran Benita <ran234@gmail.com>