6711676: Numpad keys trigger more than one KeyEvent
Introduce a new sniffer based on server keymap. Reviewed-by: art
This commit is contained in:
parent
b751a27e27
commit
c61b48b28b
@ -125,6 +125,7 @@ SUNWprivate_1.1 {
|
|||||||
Java_sun_awt_X11_XlibWrapper_XFree;
|
Java_sun_awt_X11_XlibWrapper_XFree;
|
||||||
Java_sun_awt_X11_XlibWrapper_ServerVendor;
|
Java_sun_awt_X11_XlibWrapper_ServerVendor;
|
||||||
Java_sun_awt_X11_XlibWrapper_VendorRelease;
|
Java_sun_awt_X11_XlibWrapper_VendorRelease;
|
||||||
|
Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior;
|
||||||
Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler;
|
Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler;
|
||||||
Java_sun_awt_X11_XlibWrapper_XSetErrorHandler;
|
Java_sun_awt_X11_XlibWrapper_XSetErrorHandler;
|
||||||
Java_sun_awt_X11_XlibWrapper_CallErrorHandler;
|
Java_sun_awt_X11_XlibWrapper_CallErrorHandler;
|
||||||
|
@ -145,7 +145,7 @@ public class XKeysym {
|
|||||||
{
|
{
|
||||||
// Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
|
// Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
|
||||||
// Otherwise, it is [1].
|
// Otherwise, it is [1].
|
||||||
int ndx = XToolkit.isXsunServer() &&
|
int ndx = XToolkit.isXsunKPBehavior() &&
|
||||||
! XToolkit.isXKBenabled() ? 2 : 1;
|
! XToolkit.isXKBenabled() ? 2 : 1;
|
||||||
// Even if XKB is enabled, we have another problem: some symbol tables (e.g. cz) force
|
// Even if XKB is enabled, we have another problem: some symbol tables (e.g. cz) force
|
||||||
// a regular comma instead of KP_comma for a decimal separator. Result is,
|
// a regular comma instead of KP_comma for a decimal separator. Result is,
|
||||||
@ -193,7 +193,7 @@ public class XKeysym {
|
|||||||
private static long getKeypadKeysym( XKeyEvent ev ) {
|
private static long getKeypadKeysym( XKeyEvent ev ) {
|
||||||
int ndx = 0;
|
int ndx = 0;
|
||||||
long keysym = XConstants.NoSymbol;
|
long keysym = XConstants.NoSymbol;
|
||||||
if( XToolkit.isXsunServer() &&
|
if( XToolkit.isXsunKPBehavior() &&
|
||||||
! XToolkit.isXKBenabled() ) {
|
! XToolkit.isXKBenabled() ) {
|
||||||
if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on
|
if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on
|
||||||
ndx = 3;
|
ndx = 3;
|
||||||
|
@ -2130,39 +2130,33 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private static int backingStoreType;
|
private static int backingStoreType;
|
||||||
|
|
||||||
static boolean awt_ServerInquired = false;
|
static final int XSUN_KP_BEHAVIOR = 1;
|
||||||
static boolean awt_IsXsunServer = false;
|
static final int XORG_KP_BEHAVIOR = 2;
|
||||||
|
|
||||||
|
static int awt_IsXsunKPBehavior = 0;
|
||||||
static boolean awt_UseXKB = false;
|
static boolean awt_UseXKB = false;
|
||||||
static boolean awt_UseXKB_Calls = false;
|
static boolean awt_UseXKB_Calls = false;
|
||||||
static int awt_XKBBaseEventCode = 0;
|
static int awt_XKBBaseEventCode = 0;
|
||||||
static int awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
|
static int awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
|
||||||
// to XkbTranslateKeyCode
|
// to XkbTranslateKeyCode
|
||||||
static long awt_XKBDescPtr = 0;
|
static long awt_XKBDescPtr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Try to understand if it is Xsun server.
|
* Check for Xsun convention regarding numpad keys.
|
||||||
By now (2005) Sun is vendor of Xsun and Xorg servers; we only return true if Xsun is running.
|
* Xsun and some other servers (i.e. derived from Xsun)
|
||||||
*/
|
* under certain conditions process numpad keys unlike Xorg.
|
||||||
static boolean isXsunServer() {
|
*/
|
||||||
|
static boolean isXsunKPBehavior() {
|
||||||
awtLock();
|
awtLock();
|
||||||
try {
|
try {
|
||||||
if( awt_ServerInquired ) {
|
if( awt_IsXsunKPBehavior == 0 ) {
|
||||||
return awt_IsXsunServer;
|
if( XlibWrapper.IsXsunKPBehavior(getDisplay()) ) {
|
||||||
|
awt_IsXsunKPBehavior = XSUN_KP_BEHAVIOR;
|
||||||
|
}else{
|
||||||
|
awt_IsXsunKPBehavior = XORG_KP_BEHAVIOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( ! XlibWrapper.ServerVendor(getDisplay()).startsWith("Sun Microsystems") ) {
|
return awt_IsXsunKPBehavior == XSUN_KP_BEHAVIOR ? true : false;
|
||||||
awt_ServerInquired = true;
|
|
||||||
awt_IsXsunServer = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Now, it's Sun. It still may be Xorg though, eg on Solaris 10, x86.
|
|
||||||
// Today (2005), VendorRelease of Xorg is a Big Number unlike Xsun.
|
|
||||||
if( XlibWrapper.VendorRelease(getDisplay()) > 10000 ) {
|
|
||||||
awt_ServerInquired = true;
|
|
||||||
awt_IsXsunServer = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
awt_ServerInquired = true;
|
|
||||||
awt_IsXsunServer = true;
|
|
||||||
return true;
|
|
||||||
} finally {
|
} finally {
|
||||||
awtUnlock();
|
awtUnlock();
|
||||||
}
|
}
|
||||||
|
@ -352,6 +352,7 @@ static native String XSetLocaleModifiers(String modifier_list);
|
|||||||
static native int XIconifyWindow(long display, long window, long screenNumber);
|
static native int XIconifyWindow(long display, long window, long screenNumber);
|
||||||
static native String ServerVendor(long display);
|
static native String ServerVendor(long display);
|
||||||
static native int VendorRelease(long display);
|
static native int VendorRelease(long display);
|
||||||
|
static native boolean IsXsunKPBehavior(long display);
|
||||||
|
|
||||||
static native void XBell(long display, int percent);
|
static native void XBell(long display, int percent);
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ tojava public static boolean isKPEvent( XKeyEvent ev )
|
|||||||
tojava {
|
tojava {
|
||||||
tojava // Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
|
tojava // Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
|
||||||
tojava // Otherwise, it is [1].
|
tojava // Otherwise, it is [1].
|
||||||
tojava int ndx = XToolkit.isXsunServer() &&
|
tojava int ndx = XToolkit.isXsunKPBehavior() &&
|
||||||
tojava ! XToolkit.isXKBenabled() ? 2 : 1;
|
tojava ! XToolkit.isXKBenabled() ? 2 : 1;
|
||||||
tojava // Even if XKB is enabled, we have another problem: some symbol tables (e.g. cz) force
|
tojava // Even if XKB is enabled, we have another problem: some symbol tables (e.g. cz) force
|
||||||
tojava // a regular comma instead of KP_comma for a decimal separator. Result is,
|
tojava // a regular comma instead of KP_comma for a decimal separator. Result is,
|
||||||
@ -231,7 +231,7 @@ tojava */
|
|||||||
tojava private static long getKeypadKeysym( XKeyEvent ev ) {
|
tojava private static long getKeypadKeysym( XKeyEvent ev ) {
|
||||||
tojava int ndx = 0;
|
tojava int ndx = 0;
|
||||||
tojava long keysym = XConstants.NoSymbol;
|
tojava long keysym = XConstants.NoSymbol;
|
||||||
tojava if( XToolkit.isXsunServer() &&
|
tojava if( XToolkit.isXsunKPBehavior() &&
|
||||||
tojava ! XToolkit.isXKBenabled() ) {
|
tojava ! XToolkit.isXKBenabled() ) {
|
||||||
tojava if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on
|
tojava if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on
|
||||||
tojava ndx = 3;
|
tojava ndx = 3;
|
||||||
|
@ -1181,6 +1181,38 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_VendorRelease
|
|||||||
AWT_CHECK_HAVE_LOCK();
|
AWT_CHECK_HAVE_LOCK();
|
||||||
return VendorRelease((Display*)jlong_to_ptr(display));
|
return VendorRelease((Display*)jlong_to_ptr(display));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Class: sun_awt_X11_XlibWrapper
|
||||||
|
* Method: IsXsunKPBehavior
|
||||||
|
* Signature: (J)Z;
|
||||||
|
*/
|
||||||
|
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior
|
||||||
|
(JNIEnv *env, jclass clazz, jlong display)
|
||||||
|
{
|
||||||
|
// Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
|
||||||
|
// Otherwise, it is [1] or sometimes [0].
|
||||||
|
// This sniffer first tries to determine what is a keycode for XK_KP_7
|
||||||
|
// using XKeysymToKeycode;
|
||||||
|
// second, in which place in the keysymarray is XK_KP_7
|
||||||
|
// using XKeycodeToKeysym.
|
||||||
|
int kc7;
|
||||||
|
AWT_CHECK_HAVE_LOCK();
|
||||||
|
kc7 = XKeysymToKeycode((Display*)jlong_to_ptr(display), XK_KP_7);
|
||||||
|
if( !kc7 ) {
|
||||||
|
// keycode is not defined. Why, it's a reduced keyboard perhaps:
|
||||||
|
// report arbitrarily false.
|
||||||
|
return JNI_FALSE;
|
||||||
|
} else {
|
||||||
|
long ks2 = XKeycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
|
||||||
|
if( ks2 == XK_KP_7 ) {
|
||||||
|
//XXX If some Xorg server would put XK_KP_7 in keysymarray[2] as well,
|
||||||
|
//XXX for yet unknown to me reason, the sniffer would lie.
|
||||||
|
return JNI_TRUE;
|
||||||
|
}else{
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JavaVM* jvm = NULL;
|
JavaVM* jvm = NULL;
|
||||||
static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
|
static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
|
||||||
|
Loading…
Reference in New Issue
Block a user