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 Sysout.dispose(); 102 if (mainFrame != null) { 103 mainFrame.dispose(); 104 } 105 } 106 // END - Test related code 107 108 /** 109 * *************************************************** 110 * Standard Test Machinery Section DO NOT modify anything in this section -- 111 * it's a standard chunk of code which has all of the synchronisation 112 * necessary for the test harness. By keeping it the same in all tests, it 113 * is easier to read and understand someone else's test, as well as insuring 114 * that all tests behave correctly with the test harness. There is a section 115 * following this for test-defined classes 116 * **************************************************** 117 */ 118 private static boolean theTestPassed = false; 119 private static boolean testGeneratedInterrupt = false; 120 private static String failureMessage = ""; 121 private static Thread mainThread = null; 122 private static int sleepTime = 300000; 123 124 public static void main(String args[]) throws Exception { 125 mainThread = Thread.currentThread(); 126 try { 127 init(); 128 initTestWindow(); 129 } catch (TestPassedException e) { 130 // The test passed, so just return from main and harness will 131 // interepret this return as a pass 132 return; 133 } 134 // At this point, neither test passed nor test failed has been 135 // called -- either would have thrown an exception and ended the 136 // test, so we know we have multiple threads. 137 138 // Test involves other threads, so sleep and wait for them to 139 // called pass() or fail() 140 try { 141 Thread.sleep(sleepTime); 142 // Timed out, so fail the test 143 throw new RuntimeException("Timed out after " + sleepTime / 1000 144 + " seconds"); 145 } catch (InterruptedException e) { 146 if (!testGeneratedInterrupt) { 147 dispose(); 148 throw e; 149 } 150 151 // reset flag in case hit this code more than once for some reason 152 testGeneratedInterrupt = false; 153 if (theTestPassed == false) { 154 dispose(); 155 throw new RuntimeException(failureMessage); 156 } 157 } 158 159 }// main 160 161 public static synchronized void setTimeoutTo(int seconds) { 162 sleepTime = seconds * 1000; 163 } 164 165 public static synchronized void pass() { 166 dispose(); 167 Sysout.println("The test passed."); 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 // check if this called from main thread 192 if (mainThread == Thread.currentThread()) { 193 // If main thread, fail now 'cause not sleeping 194 throw new RuntimeException(whyFailed); 195 } 196 theTestPassed = false; 197 testGeneratedInterrupt = true; 198 failureMessage = whyFailed; 199 mainThread.interrupt(); 200 }// fail() 201 }// class Orient 202 203 // This exception is used to exit from any level of call nesting 204 // when it's determined that the test has passed, and immediately 205 // end the test. 206 class TestPassedException extends RuntimeException { 207 } 208 209 // *********** End Standard Test Machinery Section ********** 210 /** 211 * ************************************************** 212 * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk 213 * of code whose purpose is to make user interaction uniform, and thereby make 214 * it simpler to read and understand someone else's test. 215 * ************************************************** 216 */ 217 /** 218 * This is part of the standard test machinery. It creates a dialog (with the 219 * instructions), and is the interface for sending text messages to the user. To 220 * print the instructions, send an array of strings to Sysout.createDialog 221 * WithInstructions method. Put one line of instructions per array entry. To 222 * display a message for the tester to see, simply call Sysout.println with the 223 * string to be displayed. This mimics System.out.println but works within the 224 * test harness as well as standalone. 225 */ 226 class Sysout { 227 228 private static TestDialog dialog; 229 230 public static void createDialogWithInstructions(String[] instructions) { 231 dialog = new TestDialog(new Frame(), "Instructions"); 232 dialog.printInstructions(instructions); 233 dialog.show(); 234 println("Any messages for the tester will display here."); 235 } 236 237 public static void createDialog() { 238 dialog = new TestDialog(new Frame(), "Instructions"); 239 String[] defInstr = {"Instructions will appear here. ", ""}; 240 dialog.printInstructions(defInstr); 241 dialog.show(); 242 println("Any messages for the tester will display here."); 243 } 244 245 public static void printInstructions(String[] instructions) { 246 dialog.printInstructions(instructions); 247 } 248 249 public static void println(String messageIn) { 250 dialog.displayMessage(messageIn); 251 } 252 253 public static void dispose() { 254 dialog.dispose(); 255 } 256 }// Sysout class 257 258 /** 259 * This is part of the standard test machinery. It provides a place for the test 260 * instructions to be displayed, and a place for interactive messages to the 261 * user to be displayed. To have the test instructions displayed, see Sysout. To 262 * have a message to the user be displayed, see Sysout. Do not call anything in 263 * this dialog directly. 264 */ 265 class TestDialog extends Dialog implements ActionListener { 266 267 TextArea instructionsText; 268 TextArea messageText; 269 int maxStringLength = 80; 270 Panel buttonP = new Panel(); 271 Button passB; 272 Button failB; 273 274 // DO NOT call this directly, go through Sysout 275 public TestDialog(Frame frame, String name) { 276 super(frame, name); 277 int scrollBoth = TextArea.SCROLLBARS_BOTH; 278 instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); 279 add("North", instructionsText); 280 281 messageText = new TextArea("", 5, maxStringLength, scrollBoth); 282 add("Center", messageText); 283 284 passB = new Button("pass"); 285 passB.setActionCommand("pass"); 286 passB.addActionListener(this); 287 buttonP.add("East", passB); 288 289 failB = new Button("fail"); 290 failB.setActionCommand("fail"); 291 failB.addActionListener(this); 292 buttonP.add("West", failB); 293 294 add("South", buttonP); 295 pack(); 296 297 show(); 298 }// TestDialog() 299 300 // DO NOT call this directly, go through Sysout 301 public void printInstructions(String[] instructions) { 302 // Clear out any current instructions 303 instructionsText.setText(""); 304 305 // Go down array of instruction strings 306 String printStr, remainingStr; 307 for (int i = 0; i < instructions.length; i++) { 308 // chop up each into pieces maxSringLength long 309 remainingStr = instructions[i]; 310 while (remainingStr.length() > 0) { 311 // if longer than max then chop off first max chars to print 312 if (remainingStr.length() >= maxStringLength) { 313 // Try to chop on a word boundary 314 int posOfSpace = remainingStr. 315 lastIndexOf(' ', maxStringLength - 1); 316 317 if (posOfSpace <= 0) { 318 posOfSpace = maxStringLength - 1; 319 } 320 321 printStr = remainingStr.substring(0, posOfSpace + 1); 322 remainingStr = remainingStr.substring(posOfSpace + 1); 323 } // else just print 324 else { 325 printStr = remainingStr; 326 remainingStr = ""; 327 } 328 instructionsText.append(printStr + "\n"); 329 }// while 330 }// for 331 }// printInstructions() 332 333 // DO NOT call this directly, go through Sysout 334 public void displayMessage(String messageIn) { 335 messageText.append(messageIn + "\n"); 336 } 337 338 // Catch presses of the passed and failed buttons. 339 // Simply call the standard pass() or fail() static methods of 340 // DialogOrient 341 public void actionPerformed(ActionEvent e) { 342 if (e.getActionCommand() == "pass") { 343 AltGraphModifierTest.pass(); 344 } else { 345 AltGraphModifierTest.fail("Incorrect modifiers"); 346 } 347 } 348 349 public void dispose() { 350 super.dispose(); 351 } 352 }// TestDialog class