1 /* 2 * Copyright (c) 2015, 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 8041928 27 @summary Confirm that the Alt-Gr Modifier bit is set correctly. 28 @run main/manual AltGraphModifierTest 29 */ 30 import java.awt.Button; 31 import java.awt.Dialog; 32 import java.awt.Frame; 33 import java.awt.Panel; 34 import java.awt.TextArea; 35 import java.awt.event.ActionEvent; 36 import java.awt.event.ActionListener; 37 import java.awt.event.InputEvent; 38 import java.awt.event.MouseAdapter; 39 import java.awt.event.MouseEvent; 40 41 public class AltGraphModifierTest { 42 43 private static void init() throws Exception { 44 // *** Create instructions for the user here *** 45 String[] instructions 46 = { 47 "This test is for verifying Alt-Gr modifier of an event.", 48 "Windows :-", 49 "1. Please check if Alt-Gr key is present on keyboard.", 50 "2. If present, press the Alt-Gr key and perform", 51 " mouse click on the TestWindow.", 52 "3. If Alt-Gr key is not present, press Ctrl+Alt keys &", 53 " perform mouse click on the TestWindow.", 54 "4. Test will exit by itself with appropriate result.", 55 "", 56 "Linux :-", 57 "1. Please check if Alt-Gr key is present on keyboard.", 58 "2. If present, press the Alt-Gr key and perform", 59 " mouse click on the TestWindow.", 60 "3. Navigate to System Settings-> Keyboard-> Shortcuts->", 61 " Typing.", 62 "4. Select an option for the Alternative Characters Key", 63 " For example. Right Alt", 64 "5. Close the settings and navigate to test", 65 "6. Press Right Alt Key & perform mouse click on the", 66 " TestWindow", 67 "7. Test will exit by itself with appropriate result.", 68 "", 69 "Mac :-", 70 " Mac fix is under progress, & will be fixed soon.", 71 " Please click Fail" 72 }; 73 74 Sysout.createDialog(); 75 Sysout.printInstructions(instructions); 76 } 77 78 // START - Test related code 79 static Frame mainFrame; 80 static TextArea textArea; 81 82 public static void initTestWindow() { 83 mainFrame = new Frame(); 84 mainFrame.setTitle("TestWindow"); 85 mainFrame.setSize(300, 200); 86 mainFrame.addMouseListener(new MouseAdapter() { 87 @Override 88 public void mousePressed(MouseEvent e) { 89 int ex = e.getModifiersEx(); 90 if ((ex & InputEvent.ALT_GRAPH_DOWN_MASK) == 0) { 91 AltGraphModifierTest.fail("Alt-Gr Modifier is not set."); 92 } else { 93 AltGraphModifierTest.pass(); 94 } 95 } 96 }); 97 mainFrame.setVisible(true); 98 } 99 100 public static void dispose() { 101 if (mainFrame != null) { 102 mainFrame.dispose(); 103 } 104 } 105 // END - Test related code 106 107 /** 108 * *************************************************** 109 * Standard Test Machinery Section DO NOT modify anything in this section -- 110 * it's a standard chunk of code which has all of the synchronisation 111 * necessary for the test harness. By keeping it the same in all tests, it 112 * is easier to read and understand someone else's test, as well as insuring 113 * that all tests behave correctly with the test harness. There is a section 114 * following this for test-defined classes 115 * **************************************************** 116 */ 117 private static boolean theTestPassed = false; 118 private static boolean testGeneratedInterrupt = false; 119 private static String failureMessage = ""; 120 private static Thread mainThread = null; 121 private static int sleepTime = 300000; 122 123 public static void main(String args[]) throws Exception { 124 mainThread = Thread.currentThread(); 125 try { 126 init(); 127 initTestWindow(); 128 } catch (TestPassedException e) { 129 // The test passed, so just return from main and harness will 130 // interepret this return as a pass 131 return; 132 } 133 // At this point, neither test passed nor test failed has been 134 // called -- either would have thrown an exception and ended the 135 // test, so we know we have multiple threads. 136 137 // Test involves other threads, so sleep and wait for them to 138 // called pass() or fail() 139 try { 140 Thread.sleep(sleepTime); 141 // Timed out, so fail the test 142 throw new RuntimeException("Timed out after " + sleepTime / 1000 143 + " seconds"); 144 } catch (InterruptedException e) { 145 if (!testGeneratedInterrupt) { 146 dispose(); 147 throw e; 148 } 149 150 // reset flag in case hit this code more than once for some reason 151 testGeneratedInterrupt = false; 152 if (theTestPassed == false) { 153 dispose(); 154 throw new RuntimeException(failureMessage); 155 } 156 } 157 158 }// main 159 160 public static synchronized void setTimeoutTo(int seconds) { 161 sleepTime = seconds * 1000; 162 } 163 164 public static synchronized void pass() { 165 dispose(); 166 Sysout.println("The test passed."); 167 Sysout.println("The test is over, hit Ctl-C to stop Java VM"); 168 // first check if this is executing in main thread 169 if (mainThread == Thread.currentThread()) { 170 // Still in the main thread, so set the flag just for kicks, 171 // and throw a test passed exception which will be caught 172 // and end the test. 173 theTestPassed = true; 174 throw new TestPassedException(); 175 } 176 // pass was called from a different thread, so set the flag 177 // and interrupt the main thead. 178 theTestPassed = true; 179 testGeneratedInterrupt = true; 180 mainThread.interrupt(); 181 }// pass() 182 183 public static synchronized void fail() { 184 // test writer didn't specify why test failed, so give generic 185 fail("it just plain failed! :-)"); 186 } 187 188 public static synchronized void fail(String whyFailed) { 189 dispose(); 190 Sysout.println("The test failed: " + whyFailed); 191 Sysout.println("The test is over, hit Ctl-C to stop Java VM"); 192 // check if this called from main thread 193 if (mainThread == Thread.currentThread()) { 194 // If main thread, fail now 'cause not sleeping 195 throw new RuntimeException(whyFailed); 196 } 197 theTestPassed = false; 198 testGeneratedInterrupt = true; 199 failureMessage = whyFailed; 200 mainThread.interrupt(); 201 }// fail() 202 }// class Orient 203 204 // This exception is used to exit from any level of call nesting 205 // when it's determined that the test has passed, and immediately 206 // end the test. 207 class TestPassedException extends RuntimeException { 208 } 209 210 // *********** End Standard Test Machinery Section ********** 211 /** 212 * ************************************************** 213 * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk 214 * of code whose purpose is to make user interaction uniform, and thereby make 215 * it simpler to read and understand someone else's test. 216 * ************************************************** 217 */ 218 /** 219 * This is part of the standard test machinery. It creates a dialog (with the 220 * instructions), and is the interface for sending text messages to the user. To 221 * print the instructions, send an array of strings to Sysout.createDialog 222 * WithInstructions method. Put one line of instructions per array entry. To 223 * display a message for the tester to see, simply call Sysout.println with the 224 * string to be displayed. This mimics System.out.println but works within the 225 * test harness as well as standalone. 226 */ 227 class Sysout { 228 229 private static TestDialog dialog; 230 231 public static void createDialogWithInstructions(String[] instructions) { 232 dialog = new TestDialog(new Frame(), "Instructions"); 233 dialog.printInstructions(instructions); 234 dialog.show(); 235 println("Any messages for the tester will display here."); 236 } 237 238 public static void createDialog() { 239 dialog = new TestDialog(new Frame(), "Instructions"); 240 String[] defInstr = {"Instructions will appear here. ", ""}; 241 dialog.printInstructions(defInstr); 242 dialog.show(); 243 println("Any messages for the tester will display here."); 244 } 245 246 public static void printInstructions(String[] instructions) { 247 dialog.printInstructions(instructions); 248 } 249 250 public static void println(String messageIn) { 251 dialog.displayMessage(messageIn); 252 } 253 254 }// Sysout class 255 256 /** 257 * This is part of the standard test machinery. It provides a place for the test 258 * instructions to be displayed, and a place for interactive messages to the 259 * user to be displayed. To have the test instructions displayed, see Sysout. To 260 * have a message to the user be displayed, see Sysout. Do not call anything in 261 * this dialog directly. 262 */ 263 class TestDialog extends Dialog implements ActionListener { 264 265 TextArea instructionsText; 266 TextArea messageText; 267 int maxStringLength = 80; 268 Panel buttonP = new Panel(); 269 Button passB; 270 Button failB; 271 272 // DO NOT call this directly, go through Sysout 273 public TestDialog(Frame frame, String name) { 274 super(frame, name); 275 int scrollBoth = TextArea.SCROLLBARS_BOTH; 276 instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); 277 add("North", instructionsText); 278 279 messageText = new TextArea("", 5, maxStringLength, scrollBoth); 280 add("Center", messageText); 281 282 passB = new Button("pass"); 283 passB.setActionCommand("pass"); 284 passB.addActionListener(this); 285 buttonP.add("East", passB); 286 287 failB = new Button("fail"); 288 failB.setActionCommand("fail"); 289 failB.addActionListener(this); 290 buttonP.add("West", failB); 291 292 add("South", buttonP); 293 pack(); 294 295 show(); 296 }// TestDialog() 297 298 // DO NOT call this directly, go through Sysout 299 public void printInstructions(String[] instructions) { 300 // Clear out any current instructions 301 instructionsText.setText(""); 302 303 // Go down array of instruction strings 304 String printStr, remainingStr; 305 for (int i = 0; i < instructions.length; i++) { 306 // chop up each into pieces maxSringLength long 307 remainingStr = instructions[i]; 308 while (remainingStr.length() > 0) { 309 // if longer than max then chop off first max chars to print 310 if (remainingStr.length() >= maxStringLength) { 311 // Try to chop on a word boundary 312 int posOfSpace = remainingStr. 313 lastIndexOf(' ', maxStringLength - 1); 314 315 if (posOfSpace <= 0) { 316 posOfSpace = maxStringLength - 1; 317 } 318 319 printStr = remainingStr.substring(0, posOfSpace + 1); 320 remainingStr = remainingStr.substring(posOfSpace + 1); 321 } // else just print 322 else { 323 printStr = remainingStr; 324 remainingStr = ""; 325 } 326 instructionsText.append(printStr + "\n"); 327 }// while 328 }// for 329 }// printInstructions() 330 331 // DO NOT call this directly, go through Sysout 332 public void displayMessage(String messageIn) { 333 messageText.append(messageIn + "\n"); 334 } 335 336 // catch presses of the passed and failed buttons. 337 // simply call the standard pass() or fail() static methods of 338 // DialogOrient 339 public void actionPerformed(ActionEvent e) { 340 if (e.getActionCommand() == "pass") { 341 AltGraphModifierTest.pass(); 342 } else { 343 AltGraphModifierTest.fail("Incorrect modifiers"); 344 } 345 } 346 }// TestDialog class