1 /*
   2  * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * test
  26  * @bug 6497426
  27  * @summary Tests that pressing of Ctrl+ascii mostly fires KEY_TYPED with a Unicode control symbols
  28  * @author Yuri.Nesterenko@... area=awt.keyboard
  29  * @run applet CtrlASCII.html
  30  */
  31 
  32 // Note there is no @ in front of test above.  This is so that the
  33 //  harness will not mistake this file as a test file.  It should
  34 //  only see the html file as a test file. (the harness runs all
  35 //  valid test files, so it would run this test twice if this file
  36 //  were valid as well as the html file.)
  37 // Also, note the area= after Your Name in the author tag.  Here, you
  38 //  should put which functional area the test falls in.  See the
  39 //  AWT-core home page -> test areas and/or -> AWT team  for a list of
  40 //  areas.
  41 // Note also the 'RobotLWTest.html' in the run tag.  This should
  42 //  be changed to the name of the test.
  43 
  44 
  45 /**
  46  * CtrlASCII.java
  47  *
  48  * @summary Tests that pressing of Ctrl+ascii mostly fires KEY_TYPED with a Unicode control symbols
  49  */
  50 
  51 import java.applet.Applet;
  52 import java.awt.*;
  53 import java.awt.event.*;
  54 import java.util.*;
  55 
  56 
  57 //
  58 // In this test, a key listener for KEY_TYPED checks if a character typed has
  59 // a correspondent keycode in an initially filled hashtable.
  60 // If it does not, test fails. If character was produced by
  61 // pressing a wrong key still listed in the hashtable, test cannot detect it.
  62 // Under MS Windows, unlike X Window, some Ctrl+Ascii keystrokes don't
  63 // produce a unicode character, so there will be no KEY_TYPED and no problem.
  64 // Test doesn't try to verify Ctrl+deadkey behavior.
  65 //
  66 
  67 public class CtrlASCII extends Applet implements KeyListener
  68 {
  69     // Declare things used in the test, like buttons and labels here
  70     static Hashtable<Character, Integer> keycharHash = new Hashtable<Character, Integer>();
  71     static boolean testFailed = false;
  72     //Frame frame;
  73     TextField tf;
  74     Robot robot;
  75 
  76     static void fillHash( boolean isMSWindows ) {
  77         keycharHash.put(    (char)0x20         , KeyEvent.VK_SPACE        );                      /*32,x20*/ /*' ' */
  78         keycharHash.put(    (char)0x21         , KeyEvent.VK_EXCLAMATION_MARK        );           /*33,x21*/ /*'!' fr*/
  79         keycharHash.put(    (char)0x22         , KeyEvent.VK_QUOTEDBL        );                   /*34,x22*/ /*'"' fr*/
  80         keycharHash.put(    (char)0x23         , KeyEvent.VK_NUMBER_SIGN        );                /*35,x23*/ /*'#' de*/
  81         keycharHash.put(    (char)0x24         , KeyEvent.VK_DOLLAR        );                      /*36,x24*/ /*'$', de_CH*/
  82         //keycharHash.put('%',                                  (char)0x25        );                                  /*37,x25*/ /*no VK, cannot test*/
  83         keycharHash.put(    (char)0x26    , KeyEvent.VK_AMPERSAND        );                  /*38,x26*/ /*'&', fr*/
  84         keycharHash.put(    (char)0x27    , KeyEvent.VK_QUOTE        );                      /*39,x27*/ /*''', fr*/
  85         keycharHash.put(    (char)0x28    , KeyEvent.VK_LEFT_PARENTHESIS        );           /*40,x28*/ /*'(', fr*/
  86         keycharHash.put(    (char)0x29    , KeyEvent.VK_RIGHT_PARENTHESIS        );           /*41,x29*/ /*')', fr*/
  87         keycharHash.put(    (char)0x2a    , KeyEvent.VK_ASTERISK        );                    /*42,x2a*/ /*'*', fr*/
  88         keycharHash.put(    (char)0x2b    , KeyEvent.VK_PLUS        );                        /*43,x2b*/ /*'+', de*/
  89         keycharHash.put(    (char)0x2c    , KeyEvent.VK_COMMA        );                       /*44,x2c*/  /*','*/
  90         keycharHash.put(    (char)0x2d    , KeyEvent.VK_MINUS        );                       /*45,x2d*/ /*'-'*/
  91         keycharHash.put(    (char)0x2e    , KeyEvent.VK_PERIOD        );                      /*46,x2e*/ /*'.'*/
  92         keycharHash.put(    (char)0x2f    , KeyEvent.VK_SLASH        );                       /*47,x2f*/ /*'/'*/
  93         keycharHash.put(    (char)0x30    , KeyEvent.VK_0        );                           /*48,x30*/
  94         keycharHash.put(    (char)0x31    , KeyEvent.VK_1        );                           /*49,x31*/
  95         keycharHash.put(    (char)0x32    , KeyEvent.VK_2        );                           /*50,x32*/
  96         keycharHash.put(    (char)0x33    , KeyEvent.VK_3        );                           /*51,x33*/
  97         keycharHash.put(    (char)0x34    , KeyEvent.VK_4        );                           /*52,x34*/
  98         keycharHash.put(    (char)0x35    , KeyEvent.VK_5        );                           /*53,x35*/
  99         keycharHash.put(    (char)0x36    , KeyEvent.VK_6        );                           /*54,x36*/
 100         keycharHash.put(    (char)0x37    , KeyEvent.VK_7        );                           /*55,x37*/
 101         keycharHash.put(    (char)0x38    , KeyEvent.VK_8        );                           /*56,x38*/
 102         keycharHash.put(    (char)0x39    , KeyEvent.VK_9        );                           /*57,x39*/
 103         keycharHash.put(    (char)0x3a    , KeyEvent.VK_COLON        );                       /*58,x3a*/ /*':', fr*/
 104         keycharHash.put(    (char)0x3b    , KeyEvent.VK_SEMICOLON        );                   /*59,x3b*/ /*';'*/
 105         keycharHash.put(    (char)0x3c    , KeyEvent.VK_LESS        );                        /*60,x3c*/ /*'<' us 102*/
 106         keycharHash.put(    (char)0x3d    , KeyEvent.VK_EQUALS        );                      /*61,x3d*/
 107         keycharHash.put(    (char)0x3e    , KeyEvent.VK_GREATER        );                     /*62,x3e*/ /*'>' ?????? where???*/
 108             // Javadoc says: "there is no keycode for the question mark because
 109             // there is no keyboard for which it appears on the primary layer."
 110             // Well, it's Lithuanian standard.
 111         //keycharHash.put('?',                                 (char)0x3f        );                                   /*63,x3f*/ /*no VK, cannot test*/
 112         keycharHash.put(    (char)0x40   , KeyEvent.VK_AT        );                          /*64,x40*/ /*'@' ?????? where???*/
 113         keycharHash.put(    (char)0x1    , KeyEvent.VK_A        );                             /*65,x41*/
 114         keycharHash.put(    (char)0x2    , KeyEvent.VK_B        );                            /*66,x42*/
 115         keycharHash.put(    (char)0x3    , KeyEvent.VK_C        );                            /*67,x43*/
 116         keycharHash.put(    (char)0x4    , KeyEvent.VK_D        );                            /*68,x44*/
 117         keycharHash.put(    (char)0x5    , KeyEvent.VK_E        );                            /*69,x45*/
 118         keycharHash.put(    (char)0x6    , KeyEvent.VK_F        );                            /*70,x46*/
 119         keycharHash.put(    (char)0x7    , KeyEvent.VK_G        );                            /*71,x47*/
 120         keycharHash.put(    (char)0x8    , KeyEvent.VK_H        );                            /*72,x48*/
 121         keycharHash.put(    (char)0x9    , KeyEvent.VK_I        );                            /*73,x49*/
 122         keycharHash.put(    (char)0xa    , KeyEvent.VK_J        );                            /*74,x4a*/
 123         keycharHash.put(    (char)0xb    , KeyEvent.VK_K        );                            /*75,x4b*/
 124         keycharHash.put(    (char)0xc    , KeyEvent.VK_L        );                            /*76,x4c*/
 125         keycharHash.put(    (char)0xd    , KeyEvent.VK_M        );                            /*77,x4d*/
 126         keycharHash.put(    (char)0xe    , KeyEvent.VK_N        );                            /*78,x4e*/
 127         keycharHash.put(    (char)0xf    , KeyEvent.VK_O        );                            /*79,x4f*/
 128         keycharHash.put(    (char)0x10   , KeyEvent.VK_P        );                           /*80,x50*/
 129         keycharHash.put(    (char)0x11   , KeyEvent.VK_Q        );                           /*81,x51*/
 130         keycharHash.put(    (char)0x12   , KeyEvent.VK_R        );                           /*82,x52*/
 131         keycharHash.put(    (char)0x13   , KeyEvent.VK_S        );                           /*83,x53*/
 132         keycharHash.put(    (char)0x14   , KeyEvent.VK_T        );                           /*84,x54*/
 133         keycharHash.put(    (char)0x15   , KeyEvent.VK_U        );                           /*85,x55*/
 134         keycharHash.put(    (char)0x16   , KeyEvent.VK_V        );                           /*86,x56*/
 135         keycharHash.put(    (char)0x17   , KeyEvent.VK_W        );                           /*87,x57*/
 136         keycharHash.put(    (char)0x18   , KeyEvent.VK_X        );                           /*88,x58*/
 137         keycharHash.put(    (char)0x19   , KeyEvent.VK_Y        );                           /*89,x59*/
 138         keycharHash.put(    (char)0x1a   , KeyEvent.VK_Z        );                           /*90,x5a*/
 139 
 140         keycharHash.put(    (char)0x1b   , KeyEvent.VK_OPEN_BRACKET        );             /*91,x5b*/ /*'['*/
 141         keycharHash.put(    (char)0x1c   , KeyEvent.VK_BACK_SLASH        );               /*92,x5c*/ /*'\'*/
 142         keycharHash.put(    (char)0x1d   , KeyEvent.VK_CLOSE_BRACKET        );            /*93,x5d*/ /*']'*/
 143         keycharHash.put(    (char)0x5e   , KeyEvent.VK_CIRCUMFLEX        );               /*94,x5e*/  /*'^' ?? nodead fr, de??*/
 144         keycharHash.put(    (char)0x1f   , KeyEvent.VK_UNDERSCORE        );               /*95,x5f*/  /*'_' fr*/
 145         keycharHash.put(    (char)0x60   , KeyEvent.VK_BACK_QUOTE        );               /*96,x60*/
 146         /********* Same as uppercase*/
 147         //keycharHash.put(  (char)0x1         , KeyEvent.VK_a        );/*97,x61*/
 148         //keycharHash.put(  (char)0x2         , KeyEvent.VK_b        );/*98,x62*/
 149         //keycharHash.put(  (char)0x3         , KeyEvent.VK_c        );/*99,x63*/
 150         //keycharHash.put(  (char)0x4         , KeyEvent.VK_d        );/*100,x64*/
 151         //keycharHash.put(  (char)0x5         , KeyEvent.VK_e        );/*101,x65*/
 152         //keycharHash.put(  (char)0x6         , KeyEvent.VK_f        );/*102,x66*/
 153         //keycharHash.put(  (char)0x7         , KeyEvent.VK_g        );/*103,x67*/
 154         //keycharHash.put(  (char)0x8         , KeyEvent.VK_h        );/*104,x68*/
 155         //keycharHash.put(  (char)0x9         , KeyEvent.VK_i        );/*105,x69*/
 156         //keycharHash.put(  (char)0xa         , KeyEvent.VK_j        );/*106,x6a*/
 157         //keycharHash.put(  (char)0xb         , KeyEvent.VK_k        );/*107,x6b*/
 158         //keycharHash.put(  (char)0xc         , KeyEvent.VK_l        );/*108,x6c*/
 159         //keycharHash.put(  (char)0xd         , KeyEvent.VK_m        );/*109,x6d*/
 160         //keycharHash.put(  (char)0xe         , KeyEvent.VK_n        );/*110,x6e*/
 161         //keycharHash.put(  (char)0xf         , KeyEvent.VK_o        );/*111,x6f*/
 162         //keycharHash.put(  (char)0x10        , KeyEvent.VK_p        );/*112,x70*/
 163         //keycharHash.put(  (char)0x11        , KeyEvent.VK_q        );/*113,x71*/
 164         //keycharHash.put(  (char)0x12        , KeyEvent.VK_r        );/*114,x72*/
 165         //keycharHash.put(  (char)0x13        , KeyEvent.VK_s        );/*115,x73*/
 166         //keycharHash.put(  (char)0x14        , KeyEvent.VK_t        );/*116,x74*/
 167         //keycharHash.put(  (char)0x15        , KeyEvent.VK_u        );/*117,x75*/
 168         //keycharHash.put(  (char)0x16        , KeyEvent.VK_v        );/*118,x76*/
 169         //keycharHash.put(  (char)0x17        , KeyEvent.VK_w        );/*119,x77*/
 170         //keycharHash.put(  (char)0x18        , KeyEvent.VK_x        );/*120,x78*/
 171         //keycharHash.put(  (char)0x19        , KeyEvent.VK_y        );/*121,x79*/
 172         //keycharHash.put(  (char)0x1a        , KeyEvent.VK_z        );/*122,x7a*/
 173 
 174         keycharHash.put(    (char)0x7b      , KeyEvent.VK_BRACELEFT        );             /*123,x7b*/ /*'{' la (Latin American)*/
 175         //keycharHash.put(  (char)0x1c        , KeyEvent.VK_|        );                   /*124,x7c*/ /* no VK, cannot test*/
 176         keycharHash.put(    (char)0x7d      , KeyEvent.VK_BRACERIGHT        );            /*125,x7d*/ /*'}' la */
 177         //keycharHash.put(  (char)0x1e        , KeyEvent.VK_~        );                   /*126,x7e*/ /* no VK, cannot test*/
 178 
 179 
 180     }
 181     public static void main(String[] args) {
 182         CtrlASCII test = new CtrlASCII();
 183         test.init();
 184         test.start();
 185     }
 186 
 187     public void init()
 188     {
 189         //Create instructions for the user here, as well as set up
 190         // the environment -- set the layout manager, add buttons,
 191         // etc.
 192         // XXX test for MS Windows
 193         fillHash( false );
 194         this.setLayout (new BorderLayout ());
 195 
 196         String[] instructions =
 197         {
 198             "This is an AUTOMATIC test",
 199             "simply wait until it is done"
 200         };
 201         Sysout.createDialog( );
 202         Sysout.printInstructions( instructions );
 203 
 204     }//End  init()
 205 
 206     public void start ()
 207     {
 208         //Get things going.  Request focus, set size, et cetera
 209 
 210         setSize(400,300);
 211         setVisible(true);
 212 
 213         //What would normally go into main() will probably go here.
 214         //Use System.out.println for diagnostic messages that you want
 215         //to read after the test is done.
 216         //Use Sysout.println for messages you want the tester to read.
 217 
 218         String original = "0123456789";
 219         tf = new TextField(original, 20);
 220         this.add(tf);
 221         tf.addKeyListener(this);
 222         validate();
 223 
 224         try {
 225             robot = new Robot();
 226             robot.setAutoWaitForIdle(true);
 227             robot.setAutoDelay(100);
 228 
 229             robot.waitForIdle();
 230 
 231             // wait for focus, etc.  (Hack.)
 232             robot.delay(2000);
 233             this.requestFocus();
 234             tf.requestFocusInWindow();
 235 
 236             Point pt = getLocationOnScreen();
 237             robot.mouseMove( pt.x+100, pt.y+100 );
 238             robot.delay(2000);
 239             robot.mousePress( InputEvent.BUTTON1_MASK );
 240             robot.mouseRelease( InputEvent.BUTTON1_MASK );
 241             Enumeration<Integer> enuElem = keycharHash.elements();
 242 
 243             int kc;
 244             while( enuElem.hasMoreElements()) {
 245                 kc = enuElem.nextElement();
 246                 punchCtrlKey( robot, kc );
 247             }
 248             robot.delay(500);
 249         } catch (Exception e) {
 250             throw new RuntimeException("The test was not completed.\n\n" + e);
 251         }
 252         if( testFailed ) {
 253             throw new RuntimeException("The test failed.\n\n");
 254         }
 255         Sysout.println("Success\n");
 256 
 257     }// start()
 258     public void punchCtrlKey( Robot ro, int keyCode ) {
 259         ro.keyPress(KeyEvent.VK_CONTROL);
 260         try {
 261             ro.keyPress(keyCode);
 262             ro.keyRelease(keyCode);
 263         }catch(IllegalArgumentException iae) {
 264             System.err.println("skip probably invalid keyCode "+keyCode);
 265         }
 266         ro.keyRelease(KeyEvent.VK_CONTROL);
 267         ro.delay(200);
 268     }
 269     public void keyPressed(KeyEvent evt)
 270     {
 271         //printKey(evt);
 272     }
 273 
 274     public void keyTyped(KeyEvent evt)
 275     {
 276         printKey(evt);
 277         char keych = evt.getKeyChar();
 278         if( !keycharHash.containsKey( keych ) ) {
 279             System.out.println("Unexpected keychar: "+keych);
 280             Sysout.println("Unexpected keychar: "+keych);
 281             testFailed = true;
 282         }
 283     }
 284 
 285     public void keyReleased(KeyEvent evt)
 286     {
 287         //printKey(evt);
 288     }
 289 
 290     protected void printKey(KeyEvent evt)
 291     {
 292         switch(evt.getID())
 293         {
 294           case KeyEvent.KEY_TYPED:
 295           case KeyEvent.KEY_PRESSED:
 296           case KeyEvent.KEY_RELEASED:
 297             break;
 298           default:
 299             System.out.println("Other Event ");
 300             Sysout.println("Other Event ");
 301             return;
 302         }
 303         System.out.print(" 0x"+ Integer.toHexString(evt.getKeyChar()));
 304         Sysout.println    (" 0x"+ Integer.toHexString(evt.getKeyChar()));
 305     }
 306 
 307 }// class CtrlASCII
 308 
 309 
 310 /****************************************************
 311  Standard Test Machinery
 312  DO NOT modify anything below -- it's a standard
 313   chunk of code whose purpose is to make user
 314   interaction uniform, and thereby make it simpler
 315   to read and understand someone else's test.
 316  ****************************************************/
 317 
 318 /**
 319  This is part of the standard test machinery.
 320  It creates a dialog (with the instructions), and is the interface
 321   for sending text messages to the user.
 322  To print the instructions, send an array of strings to Sysout.createDialog
 323   WithInstructions method.  Put one line of instructions per array entry.
 324  To display a message for the tester to see, simply call Sysout.println
 325   with the string to be displayed.
 326  This mimics System.out.println but works within the test harness as well
 327   as standalone.
 328  */
 329 
 330 class Sysout
 331  {
 332    private static TestDialog dialog;
 333 
 334    public static void createDialogWithInstructions( String[] instructions )
 335     {
 336       dialog = new TestDialog( new Frame(), "Instructions" );
 337       dialog.printInstructions( instructions );
 338       dialog.show();
 339       println( "Any messages for the tester will display here." );
 340     }
 341 
 342    public static void createDialog( )
 343     {
 344       dialog = new TestDialog( new Frame(), "Instructions" );
 345       String[] defInstr = { "Instructions will appear here. ", "" } ;
 346       dialog.printInstructions( defInstr );
 347       dialog.show();
 348       println( "Any messages for the tester will display here." );
 349     }
 350 
 351 
 352    public static void printInstructions( String[] instructions )
 353     {
 354       dialog.printInstructions( instructions );
 355     }
 356 
 357 
 358    public static void println( String messageIn )
 359     {
 360       dialog.displayMessage( messageIn );
 361     }
 362 
 363  }// Sysout  class
 364 
 365 /**
 366   This is part of the standard test machinery.  It provides a place for the
 367    test instructions to be displayed, and a place for interactive messages
 368    to the user to be displayed.
 369   To have the test instructions displayed, see Sysout.
 370   To have a message to the user be displayed, see Sysout.
 371   Do not call anything in this dialog directly.
 372   */
 373 class TestDialog extends Dialog
 374  {
 375 
 376    TextArea instructionsText;
 377    TextArea messageText;
 378    int maxStringLength = 80;
 379 
 380    //DO NOT call this directly, go through Sysout
 381    public TestDialog( Frame frame, String name )
 382     {
 383       super( frame, name );
 384       int scrollBoth = TextArea.SCROLLBARS_BOTH;
 385       instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 386       add( "North", instructionsText );
 387 
 388       messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 389       add("South", messageText);
 390 
 391       pack();
 392 
 393       show();
 394     }// TestDialog()
 395 
 396    //DO NOT call this directly, go through Sysout
 397    public void printInstructions( String[] instructions )
 398     {
 399       //Clear out any current instructions
 400       instructionsText.setText( "" );
 401 
 402       //Go down array of instruction strings
 403 
 404       String printStr, remainingStr;
 405       for( int i=0; i < instructions.length; i++ )
 406        {
 407          //chop up each into pieces maxSringLength long
 408          remainingStr = instructions[ i ];
 409          while( remainingStr.length() > 0 )
 410           {
 411             //if longer than max then chop off first max chars to print
 412             if( remainingStr.length() >= maxStringLength )
 413              {
 414                //Try to chop on a word boundary
 415                int posOfSpace = remainingStr.
 416                   lastIndexOf( ' ', maxStringLength - 1 );
 417 
 418                if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 419 
 420                printStr = remainingStr.substring( 0, posOfSpace + 1 );
 421                remainingStr = remainingStr.substring( posOfSpace + 1 );
 422              }
 423             //else just print
 424             else
 425              {
 426                printStr = remainingStr;
 427                remainingStr = "";
 428              }
 429 
 430             instructionsText.append( printStr + "\n" );
 431 
 432           }// while
 433 
 434        }// for
 435 
 436     }//printInstructions()
 437 
 438    //DO NOT call this directly, go through Sysout
 439    public void displayMessage( String messageIn )
 440     {
 441       messageText.append( messageIn + "\n" );
 442     }
 443 
 444  }// TestDialog  class