001/* 002 * Copyright (C) 2009-2017 the original author(s). 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fusesource.jansi.internal; 017 018import org.fusesource.hawtjni.runtime.*; 019 020import java.io.IOException; 021 022import static org.fusesource.hawtjni.runtime.ArgFlag.*; 023import static org.fusesource.hawtjni.runtime.ClassFlag.*; 024import static org.fusesource.hawtjni.runtime.FieldFlag.*; 025import static org.fusesource.hawtjni.runtime.MethodFlag.*; 026 027/** 028 * Interface to access Win32 base APIs. 029 * 030 * @author <a href="http://hiramchirino.com">Hiram Chirino</a> 031 */ 032@JniClass(conditional="defined(_WIN32) || defined(_WIN64)") 033public class Kernel32 { 034 035 private static final Library LIBRARY = new Library("jansi", Kernel32.class); 036 static { 037 LIBRARY.load(); 038 init(); 039 } 040 041 @JniMethod(flags={CONSTANT_INITIALIZER}) 042 private static final native void init(); 043 044 @JniField(flags={CONSTANT}) 045 public static short FOREGROUND_BLUE; 046 @JniField(flags={CONSTANT}) 047 public static short FOREGROUND_GREEN; 048 @JniField(flags={CONSTANT}) 049 public static short FOREGROUND_RED; 050 @JniField(flags={CONSTANT}) 051 public static short FOREGROUND_INTENSITY; 052 @JniField(flags={CONSTANT}) 053 public static short BACKGROUND_BLUE; 054 @JniField(flags={CONSTANT}) 055 public static short BACKGROUND_GREEN; 056 @JniField(flags={CONSTANT}) 057 public static short BACKGROUND_RED; 058 @JniField(flags={CONSTANT}) 059 public static short BACKGROUND_INTENSITY; 060 @JniField(flags={CONSTANT}) 061 public static short COMMON_LVB_LEADING_BYTE; 062 @JniField(flags={CONSTANT}) 063 public static short COMMON_LVB_TRAILING_BYTE; 064 @JniField(flags={CONSTANT}) 065 public static short COMMON_LVB_GRID_HORIZONTAL; 066 @JniField(flags={CONSTANT}) 067 public static short COMMON_LVB_GRID_LVERTICAL; 068 @JniField(flags={CONSTANT}) 069 public static short COMMON_LVB_GRID_RVERTICAL; 070 @JniField(flags={CONSTANT}) 071 public static short COMMON_LVB_REVERSE_VIDEO; 072 @JniField(flags={CONSTANT}) 073 public static short COMMON_LVB_UNDERSCORE; 074 @JniField(flags={CONSTANT}) 075 public static int FORMAT_MESSAGE_FROM_SYSTEM; 076 @JniField(flags={CONSTANT}) 077 public static int STD_INPUT_HANDLE; 078 @JniField(flags={CONSTANT}) 079 public static int STD_OUTPUT_HANDLE; 080 @JniField(flags={CONSTANT}) 081 public static int STD_ERROR_HANDLE; 082 @JniField(flags={CONSTANT}) 083 public static int INVALID_HANDLE_VALUE; 084 085 086 @JniMethod(cast="void *") 087 public static final native long malloc( 088 @JniArg(cast="size_t") long size); 089 090 public static final native void free( 091 @JniArg(cast="void *") long ptr); 092 093// public static final native void memmove ( 094// @JniArg(cast="void *") long dest, 095// @JniArg(cast="const void *") long src, 096// @JniArg(cast="size_t") long size); 097// 098// public static final native void memmove ( 099// @JniArg(cast="void *") long dest, 100// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 101// @JniArg(cast="size_t") long size); 102// 103// public static final native void memmove ( 104// @JniArg(cast="void *") long dest, 105// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, 106// @JniArg(cast="size_t") long size); 107// 108// public static final native void memmove ( 109// @JniArg(cast="void *") long dest, 110// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) short[] src, 111// @JniArg(cast="size_t") long size); 112// 113// public static final native void memmove ( 114// @JniArg(cast="void *") long dest, 115// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) int[] src, 116// @JniArg(cast="size_t") long size); 117// 118// public static final native void memmove ( 119// @JniArg(cast="void *") long dest, 120// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}, pointer=FALSE) long[] src, 121// @JniArg(cast="size_t") long size); 122// 123// public static final native void memmove ( 124// @JniArg(cast="void *") long dest, 125// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) float[] src, 126// @JniArg(cast="size_t") long size); 127// 128// public static final native void memmove ( 129// @JniArg(cast="void *") long dest, 130// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) double[] src, 131// @JniArg(cast="size_t") long size); 132// 133// 134// 135// public static final native void memmove ( 136// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 137// @JniArg(cast="const void *") long src, 138// @JniArg(cast="size_t") long size); 139// 140// public static final native void memmove ( 141// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) char[] dest, 142// @JniArg(cast="const void *") long src, 143// @JniArg(cast="size_t") long size); 144// 145// public static final native void memmove ( 146// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) short[] dest, 147// @JniArg(cast="const void *") long src, 148// @JniArg(cast="size_t") long size); 149// 150// public static final native void memmove ( 151// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 152// @JniArg(cast="const void *") long src, 153// @JniArg(cast="size_t") long size); 154// 155// public static final native void memmove ( 156// @JniArg(cast="void *", flags={NO_IN, CRITICAL}, pointer=FALSE) long[] dest, 157// @JniArg(cast="const void *") long src, 158// @JniArg(cast="size_t") long size); 159// 160// public static final native void memmove ( 161// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) float[] dest, 162// @JniArg(cast="const void *") long src, 163// @JniArg(cast="size_t") long size); 164// 165// public static final native void memmove ( 166// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) double[] dest, 167// @JniArg(cast="const void *") long src, 168// @JniArg(cast="size_t") long size); 169// 170// public static final native void memmove ( 171// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 172// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, 173// @JniArg(cast="size_t") long size); 174// 175// public static final native void memmove ( 176// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 177// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 178// @JniArg(cast="size_t") long size); 179// 180// @JniMethod(cast="void *") 181// public static final native long memset ( 182// @JniArg(cast="void *") long buffer, 183// int c, 184// @JniArg(cast="size_t") long num); 185// 186// public static final native int strlen( 187// @JniArg(cast="char *")long s); 188// 189// public static final native void memmove ( 190// @JniArg(cast="void *") long dest, 191// @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) foo src, 192// @JniArg(cast="size_t") long size); 193// 194// public static final native void memmove ( 195// @JniArg(cast="void *", flags={NO_IN, CRITICAL}) foo dest, 196// @JniArg(cast="const void *") long src, 197// @JniArg(cast="size_t") long size); 198 199 /** 200 * http://msdn.microsoft.com/en-us/library/ms686311%28VS.85%29.aspx 201 */ 202 @JniClass(flags={STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 203 static public class SMALL_RECT { 204 static { 205 LIBRARY.load(); 206 init(); 207 } 208 209 @JniMethod(flags={CONSTANT_INITIALIZER}) 210 private static final native void init(); 211 @JniField(flags={CONSTANT}, accessor="sizeof(SMALL_RECT)") 212 public static int SIZEOF; 213 214 @JniField(accessor="Left") 215 public short left; 216 @JniField(accessor="Top") 217 public short top; 218 @JniField(accessor="Right") 219 public short right; 220 @JniField(accessor="Bottom") 221 public short bottom; 222 223 public short width() { 224 return (short) (right-left); 225 } 226 public short height() { 227 return (short) (bottom-top); 228 } 229 public SMALL_RECT copy() { 230 SMALL_RECT rc = new SMALL_RECT(); 231 rc.left = left; 232 rc.top = top; 233 rc.right = right; 234 rc.bottom = bottom; 235 return rc; 236 } 237 } 238 239 /** 240 * see http://msdn.microsoft.com/en-us/library/ms686047%28VS.85%29.aspx 241 * @param consoleOutput 242 * @param attributes 243 * @return 244 */ 245 public static final native int SetConsoleTextAttribute( 246 @JniArg(cast="HANDLE")long consoleOutput, 247 short attributes); 248 249 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 250 public static class COORD { 251 252 static { 253 LIBRARY.load(); 254 init(); 255 } 256 257 @JniMethod(flags={CONSTANT_INITIALIZER}) 258 private static final native void init(); 259 @JniField(flags={CONSTANT}, accessor="sizeof(COORD)") 260 public static int SIZEOF; 261 262 @JniField(accessor="X") 263 public short x; 264 @JniField(accessor="Y") 265 public short y; 266 267 public COORD copy() { 268 COORD rc = new COORD(); 269 rc.x = x; 270 rc.y = y; 271 return rc; 272 } 273 } 274 275 /** 276 * http://msdn.microsoft.com/en-us/library/ms682093%28VS.85%29.aspx 277 */ 278 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 279 public static class CONSOLE_SCREEN_BUFFER_INFO { 280 281 static { 282 LIBRARY.load(); 283 init(); 284 } 285 286 @JniMethod(flags={CONSTANT_INITIALIZER}) 287 private static final native void init(); 288 @JniField(flags={CONSTANT}, accessor="sizeof(CONSOLE_SCREEN_BUFFER_INFO)") 289 public static int SIZEOF; 290 291 @JniField(accessor="dwSize") 292 public COORD size = new COORD(); 293 @JniField(accessor="dwCursorPosition") 294 public COORD cursorPosition = new COORD(); 295 @JniField(accessor="wAttributes") 296 public short attributes; 297 @JniField(accessor="srWindow") 298 public SMALL_RECT window = new SMALL_RECT(); 299 @JniField(accessor="dwMaximumWindowSize") 300 public COORD maximumWindowSize = new COORD(); 301 302 public int windowWidth() { 303 return window.width() + 1; 304 } 305 306 public int windowHeight() { 307 return window.height() + 1; 308 } 309 } 310 311 312 // DWORD WINAPI WaitForSingleObject( 313 // _In_ HANDLE hHandle, 314 // _In_ DWORD dwMilliseconds 315 // ); 316 public static final native int WaitForSingleObject(@JniArg(cast="HANDLE")long hHandle, int dwMilliseconds); 317 318 /** 319 * see: http://msdn.microsoft.com/en-us/library/ms724211%28VS.85%29.aspx 320 * 321 * @param handle 322 * @return 323 */ 324 public static final native int CloseHandle(@JniArg(cast="HANDLE")long handle); 325 326 327 /** 328 * see: http://msdn.microsoft.com/en-us/library/ms679360(VS.85).aspx 329 * 330 * @return 331 */ 332 public static final native int GetLastError(); 333 334 /** 335 * 336 * @param flags 337 * @param source 338 * @param messageId 339 * @param languageId 340 * @param buffer 341 * @param size 342 * @param args 343 * @return 344 */ 345 public static final native int FormatMessageW( 346 int flags, 347 @JniArg(cast="void *")long source, 348 int messageId, 349 int languageId, 350 @JniArg(cast="void *", flags={NO_IN, CRITICAL})byte[] buffer, 351 int size, 352 @JniArg(cast="void *", flags={NO_IN, CRITICAL, SENTINEL})long[] args 353 ); 354 355 356 /** 357 * See: http://msdn.microsoft.com/en-us/library/ms683171%28VS.85%29.aspx 358 * @param consoleOutput 359 * @param consoleScreenBufferInfo 360 * @return 361 */ 362 public static final native int GetConsoleScreenBufferInfo( 363 @JniArg(cast="HANDLE", flags={POINTER_ARG})long consoleOutput, 364 @JniArg(flags={NO_IN}) CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo); 365 366 /** 367 * see: http://msdn.microsoft.com/en-us/library/ms683231%28VS.85%29.aspx 368 * @param stdHandle 369 * @return 370 */ 371 @JniMethod(cast="HANDLE", flags={POINTER_RETURN}) 372 public static final native long GetStdHandle(int stdHandle); 373 374 /** 375 * http://msdn.microsoft.com/en-us/library/ms686025%28VS.85%29.aspx 376 * @param consoleOutput 377 * @param cursorPosition 378 * @return 379 */ 380 public static final native int SetConsoleCursorPosition( 381 @JniArg(cast="HANDLE", flags={POINTER_ARG})long consoleOutput, 382 @JniArg(flags={BY_VALUE,NO_OUT}) COORD cursorPosition); 383 384 /** 385 * see: http://msdn.microsoft.com/en-us/library/ms682663%28VS.85%29.aspx 386 * 387 * @param consoleOutput 388 * @param character 389 * @param length 390 * @param writeCoord 391 * @param numberOfCharsWritten 392 * @return 393 */ 394 public static final native int FillConsoleOutputCharacterW( 395 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long consoleOutput, 396 char character, 397 int length, 398 @JniArg(flags={BY_VALUE,NO_OUT}) COORD writeCoord, 399 @JniArg(flags={NO_IN}) int[] numberOfCharsWritten); 400 401 /** 402 * see: https://msdn.microsoft.com/en-us/library/ms682662%28VS.85%29.aspx 403 * 404 * @param consoleOutput 405 * @param attribute 406 * @param length 407 * @param writeCoord 408 * @param numberOfAttrsWritten 409 * @return 410 */ 411 public static final native int FillConsoleOutputAttribute( 412 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long consoleOutput, 413 short attribute, 414 int length, 415 @JniArg(flags={BY_VALUE,NO_OUT}) COORD writeCoord, 416 @JniArg(flags={NO_IN}) int[] numberOfAttrsWritten); 417 418 /** 419 * see: http://msdn.microsoft.com/en-us/library/ms687401(v=VS.85).aspx 420 * 421 * @param consoleOutput 422 * @param buffer 423 * @param numberOfCharsToWrite 424 * @param numberOfCharsWritten 425 * @param reserved must be null 426 * @return 427 */ 428 public static final native int WriteConsoleW( 429 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long consoleOutput, 430 @JniArg(flags={NO_OUT}) char[] buffer, 431 int numberOfCharsToWrite, 432 @JniArg(flags={NO_IN}) int[] numberOfCharsWritten, 433 @JniArg(cast="LPVOID", flags={POINTER_ARG})long reserved); 434 435 /** 436 * see: http://msdn.microsoft.com/en-us/library/ms683167%28VS.85%29.aspx 437 * @param handle 438 * @param mode 439 * @return 440 */ 441 public static final native int GetConsoleMode( 442 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 443 @JniArg(flags={NO_IN}) int[] mode); 444 445 /** 446 * see: http://msdn.microsoft.com/en-us/library/ms686033%28VS.85%29.aspx 447 * @param handle 448 * @param mode 449 * @return 450 */ 451 public static final native int SetConsoleMode( 452 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 453 int mode); 454 455 /** 456 * see: http://msdn.microsoft.com/en-us/library/078sfkak(VS.80).aspx 457 * @return 458 */ 459 public static final native int _getch(); 460 461 462 /** 463 * see: http://msdn.microsoft.com/en-us/library/ms686050%28VS.85%29.aspx 464 * @param title 465 * @return 0 if title was set successfully 466 */ 467 public static final native int SetConsoleTitle( 468 @JniArg(flags={UNICODE}) String title); 469 470 471 /** 472 * see: http://msdn.microsoft.com/en-us/library/ms683169(v=VS.85).aspx 473 * @return the current output code page 474 */ 475 public static final native int GetConsoleOutputCP(); 476 477 /** 478 * see: http://msdn.microsoft.com/en-us/library/ms686036(v=VS.85).aspx 479 * @param codePageID 480 * @return non 0 if code page was set 481 */ 482 public static final native int SetConsoleOutputCP(int codePageID); 483 484 /** 485 * see: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682013(v=vs.85).aspx 486 */ 487 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional = "defined(_WIN32) || defined(_WIN64)") 488 public static class CHAR_INFO { 489 490 static { 491 LIBRARY.load(); 492 init(); 493 } 494 495 @JniMethod(flags={CONSTANT_INITIALIZER}) 496 private static final native void init(); 497 @JniField(flags={CONSTANT}, accessor="sizeof(CHAR_INFO)") 498 public static int SIZEOF; 499 500 @JniField(accessor = "Attributes") 501 public short attributes; 502 @JniField(accessor="Char.UnicodeChar") 503 public char unicodeChar; 504 } 505 506 /** 507 * see: https://msdn.microsoft.com/en-us/library/windows/desktop/ms685107(v=vs.85).aspx 508 */ 509 public static final native int ScrollConsoleScreenBuffer( 510 @JniArg(cast="HANDLE", flags={POINTER_ARG})long consoleOutput, 511 @JniArg(flags={NO_OUT}) SMALL_RECT scrollRectangle, 512 @JniArg(flags={NO_OUT}) SMALL_RECT clipRectangle, 513 @JniArg(flags={BY_VALUE, NO_OUT}) COORD destinationOrigin, 514 @JniArg(flags={NO_OUT}) CHAR_INFO fill); 515 516 /** 517 * see: http://msdn.microsoft.com/en-us/library/ms684166(v=VS.85).aspx 518 */ 519 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 520 public static class KEY_EVENT_RECORD { 521 522 static { 523 LIBRARY.load(); 524 init(); 525 } 526 527 @JniMethod(flags={CONSTANT_INITIALIZER}) 528 private static final native void init(); 529 @JniField(flags={CONSTANT}, accessor="sizeof(KEY_EVENT_RECORD)") 530 public static int SIZEOF; 531 @JniField(flags={CONSTANT}, accessor="CAPSLOCK_ON") 532 public static int CAPSLOCK_ON; 533 @JniField(flags={CONSTANT}, accessor="NUMLOCK_ON") 534 public static int NUMLOCK_ON; 535 @JniField(flags={CONSTANT}, accessor="SCROLLLOCK_ON") 536 public static int SCROLLLOCK_ON; 537 @JniField(flags={CONSTANT}, accessor="ENHANCED_KEY") 538 public static int ENHANCED_KEY; 539 @JniField(flags={CONSTANT}, accessor="LEFT_ALT_PRESSED") 540 public static int LEFT_ALT_PRESSED; 541 @JniField(flags={CONSTANT}, accessor="LEFT_CTRL_PRESSED") 542 public static int LEFT_CTRL_PRESSED; 543 @JniField(flags={CONSTANT}, accessor="RIGHT_ALT_PRESSED") 544 public static int RIGHT_ALT_PRESSED; 545 @JniField(flags={CONSTANT}, accessor="RIGHT_CTRL_PRESSED") 546 public static int RIGHT_CTRL_PRESSED; 547 @JniField(flags={CONSTANT}, accessor="SHIFT_PRESSED") 548 public static int SHIFT_PRESSED; 549 550 @JniField(accessor="bKeyDown") 551 public boolean keyDown; 552 @JniField(accessor="wRepeatCount") 553 public short repeatCount; 554 @JniField(accessor="wVirtualKeyCode") 555 public short keyCode; 556 @JniField(accessor="wVirtualScanCode") 557 public short scanCode; 558 @JniField(accessor="uChar.UnicodeChar") 559 public char uchar; 560 @JniField(accessor="dwControlKeyState") 561 public int controlKeyState; 562 563 public String toString() { 564 return "KEY_EVENT_RECORD{" + 565 "keyDown=" + keyDown + 566 ", repeatCount=" + repeatCount + 567 ", keyCode=" + keyCode + 568 ", scanCode=" + scanCode + 569 ", uchar=" + uchar + 570 ", controlKeyState=" + controlKeyState + 571 '}'; 572 } 573 } 574 575 /** 576 * see: http://msdn.microsoft.com/en-us/library/ms684239(v=VS.85).aspx 577 */ 578 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 579 public static class MOUSE_EVENT_RECORD { 580 581 static { 582 LIBRARY.load(); 583 init(); 584 } 585 586 @JniMethod(flags={CONSTANT_INITIALIZER}) 587 private static final native void init(); 588 @JniField(flags={CONSTANT}, accessor="sizeof(MOUSE_EVENT_RECORD)") 589 public static int SIZEOF; 590 @JniField(flags={CONSTANT}, accessor="FROM_LEFT_1ST_BUTTON_PRESSED") 591 public static int FROM_LEFT_1ST_BUTTON_PRESSED; 592 @JniField(flags={CONSTANT}, accessor="FROM_LEFT_2ND_BUTTON_PRESSED") 593 public static int FROM_LEFT_2ND_BUTTON_PRESSED; 594 @JniField(flags={CONSTANT}, accessor="FROM_LEFT_3RD_BUTTON_PRESSED") 595 public static int FROM_LEFT_3RD_BUTTON_PRESSED; 596 @JniField(flags={CONSTANT}, accessor="FROM_LEFT_4TH_BUTTON_PRESSED") 597 public static int FROM_LEFT_4TH_BUTTON_PRESSED; 598 @JniField(flags={CONSTANT}, accessor="RIGHTMOST_BUTTON_PRESSED") 599 public static int RIGHTMOST_BUTTON_PRESSED; 600 601 @JniField(flags={CONSTANT}, accessor="CAPSLOCK_ON") 602 public static int CAPSLOCK_ON; 603 @JniField(flags={CONSTANT}, accessor="NUMLOCK_ON") 604 public static int NUMLOCK_ON; 605 @JniField(flags={CONSTANT}, accessor="SCROLLLOCK_ON") 606 public static int SCROLLLOCK_ON; 607 @JniField(flags={CONSTANT}, accessor="ENHANCED_KEY") 608 public static int ENHANCED_KEY; 609 @JniField(flags={CONSTANT}, accessor="LEFT_ALT_PRESSED") 610 public static int LEFT_ALT_PRESSED; 611 @JniField(flags={CONSTANT}, accessor="LEFT_CTRL_PRESSED") 612 public static int LEFT_CTRL_PRESSED; 613 @JniField(flags={CONSTANT}, accessor="RIGHT_ALT_PRESSED") 614 public static int RIGHT_ALT_PRESSED; 615 @JniField(flags={CONSTANT}, accessor="RIGHT_CTRL_PRESSED") 616 public static int RIGHT_CTRL_PRESSED; 617 @JniField(flags={CONSTANT}, accessor="SHIFT_PRESSED") 618 public static int SHIFT_PRESSED; 619 620 @JniField(flags={CONSTANT}, accessor="DOUBLE_CLICK") 621 public static int DOUBLE_CLICK; 622 @JniField(flags={CONSTANT}, accessor="MOUSE_HWHEELED") 623 public static int MOUSE_HWHEELED; 624 @JniField(flags={CONSTANT}, accessor="MOUSE_MOVED") 625 public static int MOUSE_MOVED; 626 @JniField(flags={CONSTANT}, accessor="MOUSE_WHEELED") 627 public static int MOUSE_WHEELED; 628 629 @JniField(accessor="dwMousePosition") 630 public COORD mousePosition = new COORD(); 631 @JniField(accessor="dwButtonState") 632 public int buttonState; 633 @JniField(accessor="dwControlKeyState") 634 public int controlKeyState; 635 @JniField(accessor="dwEventFlags") 636 public int eventFlags; 637 638 public String toString() { 639 return "MOUSE_EVENT_RECORD{" + 640 "mousePosition=" + mousePosition + 641 ", buttonState=" + buttonState + 642 ", controlKeyState=" + controlKeyState + 643 ", eventFlags=" + eventFlags + 644 '}'; 645 } 646 } 647 648 /** 649 * see: http://msdn.microsoft.com/en-us/library/ms687093(v=VS.85).aspx 650 */ 651 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 652 public static class WINDOW_BUFFER_SIZE_RECORD { 653 654 static { 655 LIBRARY.load(); 656 init(); 657 } 658 659 @JniMethod(flags={CONSTANT_INITIALIZER}) 660 private static final native void init(); 661 @JniField(flags={CONSTANT}, accessor="sizeof(WINDOW_BUFFER_SIZE_RECORD)") 662 public static int SIZEOF; 663 664 @JniField(accessor="dwSize") 665 public COORD size = new COORD(); 666 667 public String toString() { 668 return "WINDOW_BUFFER_SIZE_RECORD{size=" + size + '}'; 669 } 670 } 671 672 /** 673 * see: http://msdn.microsoft.com/en-us/library/ms683149(v=VS.85).aspx 674 */ 675 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 676 public static class FOCUS_EVENT_RECORD { 677 static { 678 LIBRARY.load(); 679 init(); 680 } 681 @JniMethod(flags={CONSTANT_INITIALIZER}) 682 private static final native void init(); 683 @JniField(flags={CONSTANT}, accessor="sizeof(WINDOW_BUFFER_SIZE_RECORD)") 684 public static int SIZEOF; 685 @JniField(accessor="bSetFocus") 686 public boolean setFocus; 687 } 688 689 /** 690 * see: http://msdn.microsoft.com/en-us/library/ms684213(v=VS.85).aspx 691 */ 692 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 693 public static class MENU_EVENT_RECORD { 694 static { 695 LIBRARY.load(); 696 init(); 697 } 698 @JniMethod(flags={CONSTANT_INITIALIZER}) 699 private static final native void init(); 700 @JniField(flags={CONSTANT}, accessor="sizeof(MENU_EVENT_RECORD)") 701 public static int SIZEOF; 702 @JniField(accessor="dwCommandId") 703 public int commandId; 704 } 705 706 /** 707 * see: http://msdn.microsoft.com/en-us/library/ms683499(v=VS.85).aspx 708 */ 709 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 710 public static class INPUT_RECORD { 711 712 static { 713 LIBRARY.load(); 714 init(); 715 } 716 717 @JniMethod(flags={CONSTANT_INITIALIZER}) 718 private static final native void init(); 719 @JniField(flags={CONSTANT}, accessor="sizeof(INPUT_RECORD)") 720 public static int SIZEOF; 721 @JniField(flags={CONSTANT}, accessor="KEY_EVENT") 722 public static short KEY_EVENT; 723 @JniField(flags={CONSTANT}, accessor="MOUSE_EVENT") 724 public static short MOUSE_EVENT; 725 @JniField(flags={CONSTANT}, accessor="WINDOW_BUFFER_SIZE_EVENT") 726 public static short WINDOW_BUFFER_SIZE_EVENT; 727 @JniField(flags={CONSTANT}, accessor="FOCUS_EVENT") 728 public static short FOCUS_EVENT; 729 @JniField(flags={CONSTANT}, accessor="MENU_EVENT") 730 public static short MENU_EVENT; 731 @JniField(accessor="EventType") 732 public short eventType; 733 @JniField(accessor="Event.KeyEvent") 734 public KEY_EVENT_RECORD keyEvent = new KEY_EVENT_RECORD(); 735 @JniField(accessor="Event.MouseEvent") 736 public MOUSE_EVENT_RECORD mouseEvent = new MOUSE_EVENT_RECORD(); 737 @JniField(accessor="Event.WindowBufferSizeEvent") 738 public WINDOW_BUFFER_SIZE_RECORD windowBufferSizeEvent = new WINDOW_BUFFER_SIZE_RECORD(); 739 @JniField(accessor="Event.MenuEvent") 740 public MENU_EVENT_RECORD menuEvent = new MENU_EVENT_RECORD(); 741 @JniField(accessor="Event.FocusEvent") 742 public FOCUS_EVENT_RECORD focusEvent = new FOCUS_EVENT_RECORD(); 743 744 public static final native void memmove ( 745 @JniArg(cast="void *", flags={NO_IN, CRITICAL}) INPUT_RECORD dest, 746 @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) long src, 747 @JniArg(cast="size_t") long size); 748 749 } 750 751 /** 752 * see: http://msdn.microsoft.com/en-us/library/ms684961(v=VS.85).aspx 753 * @param handle 754 * @param length 755 * @param eventsCount 756 * @return 757 */ 758 private static final native int ReadConsoleInputW( 759 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 760 @JniArg(cast="PINPUT_RECORD", flags={POINTER_ARG}) long inputRecord, 761 int length, 762 @JniArg(flags={NO_IN}) int[] eventsCount); 763 764 /** 765 * see: http://msdn.microsoft.com/en-us/library/ms684344(v=VS.85).aspx 766 * @param handle 767 * @param length 768 * @param eventsCount 769 * @return 770 */ 771 private static final native int PeekConsoleInputW( 772 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 773 @JniArg(cast="PINPUT_RECORD", flags={POINTER_ARG}) long inputRecord, 774 int length, 775 @JniArg(flags={NO_IN}) int[] eventsCount); 776 777 /** 778 * see: http://msdn.microsoft.com/en-us/library/ms683207(v=VS.85).aspx 779 * @param handle 780 * @param numberOfEvents number of unread input records in the console's input buffer 781 * @return 782 */ 783 public static final native int GetNumberOfConsoleInputEvents( 784 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 785 @JniArg(flags={NO_IN}) int[] numberOfEvents); 786 787 /** 788 * see: http://msdn.microsoft.com/en-us/library/ms683147(v=VS.85).aspx 789 * @param handle 790 * @return 791 */ 792 public static final native int FlushConsoleInputBuffer( 793 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle); 794 795 /** 796 * Return console input events. 797 * 798 * @param handle 799 * @param count requested number of events 800 * @return null on read errors 801 */ 802 public static INPUT_RECORD[] readConsoleInputHelper( 803 long handle, int count, boolean peek) throws IOException { 804 int[] length = new int[1]; 805 int res; 806 long inputRecordPtr = 0; 807 try { 808 inputRecordPtr = malloc(INPUT_RECORD.SIZEOF * count); 809 if (inputRecordPtr == 0) { 810 throw new IOException("cannot allocate memory with JNI"); 811 } 812 res = peek ? 813 PeekConsoleInputW(handle, inputRecordPtr, count, length) 814 : ReadConsoleInputW(handle, inputRecordPtr, count, length); 815 if (res == 0) { 816 throw new IOException("ReadConsoleInputW failed"); 817 } 818 if (length[0] <= 0) { 819 return new INPUT_RECORD[0]; 820 } 821 INPUT_RECORD[] records = new INPUT_RECORD[length[0]]; 822 for (int i = 0; i < records.length; i++) { 823 records[i] = new INPUT_RECORD(); 824 INPUT_RECORD.memmove(records[i], PointerMath.add(inputRecordPtr, i*INPUT_RECORD.SIZEOF), INPUT_RECORD.SIZEOF); 825 } 826 return records; 827 } finally { 828 if (inputRecordPtr != 0) { 829 free(inputRecordPtr); 830 } 831 } 832 } 833 834 /** 835 * Return console input key events (discard other events). 836 * 837 * @param count requested number of events 838 * @return array possibly of size smaller then count 839 */ 840 public static INPUT_RECORD[] readConsoleKeyInput(long handle, int count, boolean peek) 841 throws IOException { 842 while (true) { 843 // read events until we have keyboard events, the queue could be full 844 // of mouse events. 845 INPUT_RECORD[] evts = readConsoleInputHelper(handle, count, peek); 846 int keyEvtCount = 0; 847 for (INPUT_RECORD evt : evts) { 848 if (evt.eventType == INPUT_RECORD.KEY_EVENT) keyEvtCount++; 849 } 850 if (keyEvtCount > 0) { 851 INPUT_RECORD[] res = new INPUT_RECORD[keyEvtCount]; 852 int i = 0; 853 for (INPUT_RECORD evt : evts) { 854 if (evt.eventType == INPUT_RECORD.KEY_EVENT) { 855 res[i++] = evt; 856 } 857 } 858 return res; 859 } 860 } 861 } 862 863 864}