JDK-4799499 : dead key followed by space should produce non-dead character on Unix
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0,6
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    linux,linux_redhat_6.1,linux_redhat_9.0 linux,linux_redhat_6.1,linux_redhat_9.0
  • CPU: x86
  • Submitted: 2003-01-07
  • Updated: 2005-06-06
  • Resolved: 2005-06-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b40Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Non-Java applications can produce ascii versions of dead keys by typing 
the dead key followed by the space key.  For example, in a German xmodmap,  dead-acute followed by space produces apostrophe.  dead-circumflex followed 
by space produces ascii circumflex.  

The test case below can be used to see that this does not work in JDK1.4.2 
with lightweight TextComponents (including Swing).  

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;        

public class MySwingTest extends JApplet implements KeyListener, ActionListener {

    JTextField jtf = null; 
    JTextArea jta = null; 

    public static void main(String[] args) {
        JFrame frame = new JFrame("MySwingTest");
        JPanel p = new JPanel();

        MySwingTest applet = new MySwingTest();
        applet.init();

        p.add("Center", applet);
        frame.getContentPane().add(p);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setSize(850, 200);
        frame.setVisible(true);

        applet.start();
    }

    public void init() { 
        JLabel jl = new JLabel("Enter characters");

        jtf = new JTextField("Hello World", 20);
        jtf.addKeyListener(this);
        jtf.addActionListener(this);
        jta = new JTextArea("Hello World", 4, 30);
        jta.addKeyListener(this);

        // the default layout manager for a JApplet is a BorderLayout 
        this.getContentPane().setLayout(new FlowLayout());
        this.getContentPane().add(jl, FlowLayout.LEFT);
        this.getContentPane().add(jtf, FlowLayout.CENTER);
        this.getContentPane().add(jta, FlowLayout.RIGHT);
    }

    public void start() { 
        jtf.requestFocus();
    }

    public void keyPressed(KeyEvent evt)
    {
        printKey(evt);
    }

    public void keyTyped(KeyEvent evt)
    {
        printKey(evt);
    }

    public void keyReleased(KeyEvent evt)
    {
        printKey(evt);
        System.out.print("\n");
    }

    public void actionPerformed(ActionEvent evt)
    {
        System.out.print("\n");
        System.out.print("Action Event\n");
        System.out.println(evt.toString());
        System.out.print("\n");
    }

    protected void printKey(KeyEvent evt)
    {
        switch(evt.getID())
        {
          case KeyEvent.KEY_TYPED:
            break;
          case KeyEvent.KEY_PRESSED:
            break;
          case KeyEvent.KEY_RELEASED:
            break;
          default:
            System.out.println("Other Event ");
            return;
        }

        System.out.print("params= " + evt.paramString() + "  \n" +
          "KeyChar: " + evt.getKeyChar() + " = " + (int) evt.getKeyChar() +
          "   KeyCode: " + evt.getKeyCode() +
          "   Modifiers: " + evt.getModifiers());
        if (evt.isActionKey())
            System.out.print("   Action Key");
        System.out.print("\n");

        System.out.println("keyText= " + evt.getKeyText(evt.getKeyCode())
          + "\n");
    }

}
###@###.### 11/2/04 09:55 GMT

Comments
SUGGESTED FIX Suggested fix to this problem may and most probably will break some other functionality, so let's keep it conditional. Essential changes go to src/solaris/native/sun/xawt/XWindow.c, and property handling go somewhere else: I don't know how it should be done properly as code is not our. ------- XWindow.c ------- 72a73 > jfieldID composed_ascii_hackID; 941a943,945 > jint composed_ascii_hack = 0; > > composed_ascii_hack = (*env)->GetIntField(env, peer, composed_ascii_hackID); 944a949,950 > printf("Entered handleKeyEvent: type=%d, xkeycode=0x%x, xstate=0x%x, keysym=0x%x, composed_ascii_hack=%d\n", > event->type, event->xkey.keycode, event->xkey.state, keysym, composed_ascii_hack); 969c975,985 < keysym = XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0); --- > > /* Certain ascii keysyms come with keycode 0 out of IM. An example: dead_acute followed > * by space is apostrophe, and keycode is 0. > * In this case, an additional XLookupString or XKeycodeToKeysym call would return zeros. > * Conditionally, we'll bypass these calls; it will fix 4799499 but most probably break > * some locales with direct input of accented keys. Or doesn't it? > */ > if( !composed_ascii_hack || event->xkey.keycode != 0 ) { > keysym = XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0); > } > printf("handleKeyEvent: keysym recalculated:0x%x; remember, NoSymbol is 0x%x\n", keysym, NoSymbol ); 997,998c1013,1018 < < charcount = XLookupString(&(event->xkey), buffer, bufsize-1, &keysym, &status_in_out); --- > > if( !composed_ascii_hack || event->xkey.keycode != 0 ) { > charcount = XLookupString(&(event->xkey), buffer, bufsize-1, &keysym, &status_in_out); > }else{ > charcount = 0; > } 1338a1359,1360 > composed_ascii_hackID = (*env)->GetFieldID(env, clazz, "composed_ascii_hack", "I"); > // And here I just get a property value from the System. ------- XWindow.java ------- *** /tmp/sccs.zUxEH9 2004-11-02 13:02:44.000000000 +0300 --- XWindow.java 2004-11-02 13:02:34.000000000 +0300 *************** *** 66,71 **** --- 66,73 ---- // fallback default font object final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); + private int composed_ascii_hack; + native int getNativeColor(Color clr, GraphicsConfiguration gc); native void getWMInsets(long window, long left, long top, long right, long bottom, long border); *************** *** 146,151 **** --- 148,154 ---- params.putIfNull(BOUNDS, new Rectangle(0, 0, MIN_SIZE, MIN_SIZE)); } params.putIfNull(BORDER_PIXEL, new Long(0)); + composed_ascii_hack = System.getProperty("sun.awt.composed.ascii") == null ? 0 : 1; getColorModel(); // fix 4948833: this call forces the color map to be initialized params.putIfNull(COLORMAP, gData.get_awt_cmap()); params.putIfNull(DEPTH, gData.get_awt_depth()); ###@###.### 11/2/04 10:04 GMT
02-11-2004

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang
01-10-2004

EVALUATION Commit to fix in Tiger. ###@###.### 2003-01-06 This rurned out to be much more difficult than expected. Our key event translation model has some serious deficiencies which require a rewrite. I added a bunch of debugging code and comments in the XAWT implementation (XWindow.c) explaining where the problems lie. Also, the work I tried with motif-based AWT and XLookupString was a failure. It seems that doing the translations to support lightweight (e.g. swing) components and motif components are mutually incompatible (probably since motif does its own translation), so we will probably just fix this in XAWT. We'll have to put this off until a later release. ###@###.### 2004-01-08 A roots of our difficulties with this bug (and many similar bugs) are in unnecessary duplication - sometimes even triplication - of some functions belonging to Input Method code. For instance, we try to determine keychar using key event data _after_ IM has it processed; however IM code changes some fields of original event, by convention; as a result, certain keys are swallowed. We need to streamline key processing again, in cooperation with IM team. In the meantime, if a fix to this bug is so urgently needed, we can provide yet another patch; as I don't know what exactly will be broken by this patch, I'd propose to make it conditional, a property-driven. We invent a runtime property and if it is set, switch off some redundant checks in our old code. ###@###.### 11/2/04 09:55 GMT After fix to 4360364, XAWT version should work properly in Mustang. ###@###.### 2005-05-25 10:17:48 GMT
02-11-0004