Do XkbKSIsLower() and XkbKSIsUpper() matter?
Alan Coopersmith
alan.coopersmith at oracle.com
Sat Oct 26 23:04:55 CEST 2013
I tried a build with gcc's -Wlogicalops flag to see what other fun it would
find, and of course, it triggered in XKB code, in libxkbfile:
xkbmisc.c: In function '_XkbKSCheckCase':
xkbmisc.c:100:13: warning: logical 'and' of mutually exclusive tests is always false [-Wlogical-op]
xkbmisc.c:114:13: warning: logical 'and' of mutually exclusive tests is always false [-Wlogical-op]
Looking at the code, it's in the function to determine if a KeySym is upper case
or lower case, and triggered on the "latin 8" section of that:
54 set = (ks & (~0xff)) >> 8;
55 rtrn = 0;
56 switch (set) {
[...]
97 case 18: /* latin 8 */
98 if ((ks == XK_Babovedot) ||
99 ((ks >= XK_Dabovedot) && (ks <= XK_Wacute)) ||
100 ((ks >= XK_Ygrave) && (ks <= XK_Fabovedot)) ||
101 (ks == XK_Mabovedot) ||
102 (ks == XK_Pabovedot) ||
103 (ks == XK_Sabovedot) ||
104 (ks == XK_Wdiaeresis) ||
105 ((ks >= XK_Wcircumflex) && (ks <= XK_Ycircumflex))) {
106 rtrn |= _XkbKSUpper;
107 }
108 if ((ks == XK_babovedot) ||
109 (ks == XK_dabovedot) ||
110 (ks == XK_fabovedot) ||
111 (ks == XK_mabovedot) ||
112 ((ks >= XK_wgrave) && (ks <= XK_wacute)) ||
113 (ks == XK_ygrave) ||
114 ((ks >= XK_wdiaeresis) && (ks <= XK_ycircumflex))) {
115 rtrn |= _XkbKSLower;
116 }
117 break;
And indeed if you compare against <X11/keymdef.h>, lines 100 & 114 have
impossible conditions:
((ks >= XK_Ygrave) && (ks <= XK_Fabovedot))
#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
((ks >= XK_wdiaeresis) && (ks <= XK_ycircumflex))
#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
At first I figured this was just another instance of the issue KiBi noted in
http://cgit.freedesktop.org/xorg/proto/x11proto/commit/keysymdef.h?id=9bbb6e3f835219110ec0f7bd72ba7fa92974bae8
where the sort order confused people into making invalid range checks.
So I wrote a quick test program ( https://gist.github.com/alanc/7174179 )
and expected to see some confusion. Instead ./xkbcasetest 0x1001e02..0x1001ef3
showed none of the keysyms in this range were flagged upper or lower case.
This confused me until I noticed the case statement - these keysyms are only
checked if the keysym value is 0x000012xx, but they're all 0x01001Exx, so
they're never checked. Changing the case statement to case 0x01001E did
get the confusing results I originally expected:
XK_Wgrave 01001e80 upper
XK_wgrave 01001e81 upper lower
XK_Wacute 01001e82 upper lower
XK_wacute 01001e83 lower
XK_Wdiaeresis 01001e84 upper
XK_wdiaeresis 01001e85
Digging back further, it seems this code was never updated after the
Unicodification of the keysyms renumbered all of them, back in 2004:
http://cgit.freedesktop.org/xorg/proto/x11proto/commit/keysymdef.h?id=618956f1f783a8c330aab8eac425937f0b8e50e1
So while I could fix up the Latin 8 mappings here, doing all of Unicode
would be more challenging - and if no one has noticed in nearly a decade,
probably not worth it.
The only hits google found for XkbKSIsUpper() were copies of our source
code - this implementation in libxkbfile and a historical call in the X11R6.6
app/xkbcomp/tree/symbols.c which was replaced with a different implementation
when we merged in the XFree86 4.4rc changes:
http://cgit.freedesktop.org/xorg/app/xkbcomp/commit/symbols.c?id=a153e2624e9e3e7b06fad207e8855bea617ac088
Does anyone know of any reason to waste time on this function? Can we just
delete it altogther now? (libxkbfile is undocumented, and was originally
considered private API, but we know software like GNOME has used it in the
past.)
--
-Alan Coopersmith- alan.coopersmith at oracle.com
Oracle Solaris Engineering - http://blogs.oracle.com/alanc
More information about the xorg-devel
mailing list