001 /** 002 * Copyright (C) 2009, Progress Software Corporation and/or its 003 * subsidiaries or affiliates. All rights reserved. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.fusesource.jansi.internal; 018 019 import org.fusesource.hawtjni.runtime.ClassFlag; 020 import org.fusesource.hawtjni.runtime.JniArg; 021 import org.fusesource.hawtjni.runtime.JniClass; 022 import org.fusesource.hawtjni.runtime.JniField; 023 import org.fusesource.hawtjni.runtime.JniMethod; 024 import org.fusesource.hawtjni.runtime.Library; 025 026 import static org.fusesource.hawtjni.runtime.ArgFlag.*; 027 import static org.fusesource.hawtjni.runtime.ClassFlag.*; 028 import static org.fusesource.hawtjni.runtime.FieldFlag.*; 029 import static org.fusesource.hawtjni.runtime.MethodFlag.*; 030 031 /** 032 * 033 * @author <a href="http://hiramchirino.com">Hiram Chirino</a> 034 */ 035 @JniClass(conditional="defined(_WIN32) || defined(_WIN64)") 036 public class Kernel32 { 037 038 private static final Library LIBRARY = new Library("jansi", Kernel32.class); 039 static { 040 LIBRARY.load(); 041 init(); 042 } 043 044 @JniMethod(flags={CONSTANT_INITIALIZER}) 045 private static final native void init(); 046 047 @JniField(flags={CONSTANT}) 048 public static short FOREGROUND_BLUE; 049 @JniField(flags={CONSTANT}) 050 public static short FOREGROUND_GREEN; 051 @JniField(flags={CONSTANT}) 052 public static short FOREGROUND_RED; 053 @JniField(flags={CONSTANT}) 054 public static short FOREGROUND_INTENSITY; 055 @JniField(flags={CONSTANT}) 056 public static short BACKGROUND_BLUE; 057 @JniField(flags={CONSTANT}) 058 public static short BACKGROUND_GREEN; 059 @JniField(flags={CONSTANT}) 060 public static short BACKGROUND_RED; 061 @JniField(flags={CONSTANT}) 062 public static short BACKGROUND_INTENSITY; 063 @JniField(flags={CONSTANT}) 064 public static short COMMON_LVB_LEADING_BYTE; 065 @JniField(flags={CONSTANT}) 066 public static short COMMON_LVB_TRAILING_BYTE; 067 @JniField(flags={CONSTANT}) 068 public static short COMMON_LVB_GRID_HORIZONTAL; 069 @JniField(flags={CONSTANT}) 070 public static short COMMON_LVB_GRID_LVERTICAL; 071 @JniField(flags={CONSTANT}) 072 public static short COMMON_LVB_GRID_RVERTICAL; 073 @JniField(flags={CONSTANT}) 074 public static short COMMON_LVB_REVERSE_VIDEO; 075 @JniField(flags={CONSTANT}) 076 public static short COMMON_LVB_UNDERSCORE; 077 @JniField(flags={CONSTANT}) 078 public static int FORMAT_MESSAGE_FROM_SYSTEM; 079 @JniField(flags={CONSTANT}) 080 public static int STD_INPUT_HANDLE; 081 @JniField(flags={CONSTANT}) 082 public static int STD_OUTPUT_HANDLE; 083 @JniField(flags={CONSTANT}) 084 public static int STD_ERROR_HANDLE; 085 @JniField(flags={CONSTANT}) 086 public static int INVALID_HANDLE_VALUE; 087 088 089 @JniMethod(cast="void *") 090 public static final native long malloc( 091 @JniArg(cast="size_t") long size); 092 093 public static final native void free( 094 @JniArg(cast="void *") long ptr); 095 096 // public static final native void memmove ( 097 // @JniArg(cast="void *") long dest, 098 // @JniArg(cast="const void *") long src, 099 // @JniArg(cast="size_t") long size); 100 // 101 // public static final native void memmove ( 102 // @JniArg(cast="void *") long dest, 103 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 104 // @JniArg(cast="size_t") long size); 105 // 106 // public static final native void memmove ( 107 // @JniArg(cast="void *") long dest, 108 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, 109 // @JniArg(cast="size_t") long size); 110 // 111 // public static final native void memmove ( 112 // @JniArg(cast="void *") long dest, 113 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) short[] src, 114 // @JniArg(cast="size_t") long size); 115 // 116 // public static final native void memmove ( 117 // @JniArg(cast="void *") long dest, 118 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) int[] src, 119 // @JniArg(cast="size_t") long size); 120 // 121 // public static final native void memmove ( 122 // @JniArg(cast="void *") long dest, 123 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}, pointer=FALSE) long[] src, 124 // @JniArg(cast="size_t") long size); 125 // 126 // public static final native void memmove ( 127 // @JniArg(cast="void *") long dest, 128 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) float[] src, 129 // @JniArg(cast="size_t") long size); 130 // 131 // public static final native void memmove ( 132 // @JniArg(cast="void *") long dest, 133 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) double[] src, 134 // @JniArg(cast="size_t") long size); 135 // 136 // 137 // 138 // public static final native void memmove ( 139 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 140 // @JniArg(cast="const void *") long src, 141 // @JniArg(cast="size_t") long size); 142 // 143 // public static final native void memmove ( 144 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) char[] dest, 145 // @JniArg(cast="const void *") long src, 146 // @JniArg(cast="size_t") long size); 147 // 148 // public static final native void memmove ( 149 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) short[] dest, 150 // @JniArg(cast="const void *") long src, 151 // @JniArg(cast="size_t") long size); 152 // 153 // public static final native void memmove ( 154 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 155 // @JniArg(cast="const void *") long src, 156 // @JniArg(cast="size_t") long size); 157 // 158 // public static final native void memmove ( 159 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}, pointer=FALSE) long[] dest, 160 // @JniArg(cast="const void *") long src, 161 // @JniArg(cast="size_t") long size); 162 // 163 // public static final native void memmove ( 164 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) float[] dest, 165 // @JniArg(cast="const void *") long src, 166 // @JniArg(cast="size_t") long size); 167 // 168 // public static final native void memmove ( 169 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) double[] dest, 170 // @JniArg(cast="const void *") long src, 171 // @JniArg(cast="size_t") long size); 172 // 173 // public static final native void memmove ( 174 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 175 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, 176 // @JniArg(cast="size_t") long size); 177 // 178 // public static final native void memmove ( 179 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 180 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 181 // @JniArg(cast="size_t") long size); 182 // 183 // @JniMethod(cast="void *") 184 // public static final native long memset ( 185 // @JniArg(cast="void *") long buffer, 186 // int c, 187 // @JniArg(cast="size_t") long num); 188 // 189 // public static final native int strlen( 190 // @JniArg(cast="char *")long s); 191 // 192 // public static final native void memmove ( 193 // @JniArg(cast="void *") long dest, 194 // @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) foo src, 195 // @JniArg(cast="size_t") long size); 196 // 197 // public static final native void memmove ( 198 // @JniArg(cast="void *", flags={NO_IN, CRITICAL}) foo dest, 199 // @JniArg(cast="const void *") long src, 200 // @JniArg(cast="size_t") long size); 201 202 /** 203 * http://msdn.microsoft.com/en-us/library/ms686311%28VS.85%29.aspx 204 */ 205 @JniClass(flags={STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 206 static public class SMALL_RECT { 207 static { 208 LIBRARY.load(); 209 init(); 210 } 211 212 @JniMethod(flags={CONSTANT_INITIALIZER}) 213 private static final native void init(); 214 @JniField(flags={CONSTANT}, accessor="sizeof(SMALL_RECT)") 215 public static int SIZEOF; 216 217 @JniField(accessor="Left") 218 public short left; 219 @JniField(accessor="Top") 220 public short top; 221 @JniField(accessor="Right") 222 public short right; 223 @JniField(accessor="Bottom") 224 public short bottom; 225 226 public short width() { 227 return (short) (right-left); 228 } 229 public short height() { 230 return (short) (bottom-top); 231 } 232 } 233 234 /** 235 * see http://msdn.microsoft.com/en-us/library/ms686047%28VS.85%29.aspx 236 * @param consoleOutput 237 * @param attributes 238 * @return 239 */ 240 public static final native int SetConsoleTextAttribute( 241 @JniArg(cast="HANDLE")long consoleOutput, 242 short attributes); 243 244 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 245 public static class COORD { 246 247 static { 248 LIBRARY.load(); 249 init(); 250 } 251 252 @JniMethod(flags={CONSTANT_INITIALIZER}) 253 private static final native void init(); 254 @JniField(flags={CONSTANT}, accessor="sizeof(COORD)") 255 public static int SIZEOF; 256 257 @JniField(accessor="X") 258 public short x; 259 @JniField(accessor="Y") 260 public short y; 261 262 public COORD copy() { 263 COORD rc = new COORD(); 264 rc.x = x; 265 rc.y = y; 266 return rc; 267 } 268 } 269 270 /** 271 * http://msdn.microsoft.com/en-us/library/ms682093%28VS.85%29.aspx 272 */ 273 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 274 public static class CONSOLE_SCREEN_BUFFER_INFO { 275 276 static { 277 LIBRARY.load(); 278 init(); 279 } 280 281 @JniMethod(flags={CONSTANT_INITIALIZER}) 282 private static final native void init(); 283 @JniField(flags={CONSTANT}, accessor="sizeof(CONSOLE_SCREEN_BUFFER_INFO)") 284 public static int SIZEOF; 285 286 @JniField(accessor="dwSize") 287 public COORD size = new COORD(); 288 @JniField(accessor="dwCursorPosition") 289 public COORD cursorPosition = new COORD(); 290 @JniField(accessor="wAttributes") 291 public short attributes; 292 @JniField(accessor="srWindow") 293 public SMALL_RECT window = new SMALL_RECT(); 294 @JniField(accessor="dwMaximumWindowSize") 295 public COORD maximumWindowSize = new COORD(); 296 297 public int windowWidth() { 298 return window.width() + 1; 299 } 300 301 public int windowHeight() { 302 return window.height() + 1; 303 } 304 } 305 306 307 /** 308 * see: http://msdn.microsoft.com/en-us/library/ms724211%28VS.85%29.aspx 309 * 310 * @param handle 311 * @return 312 */ 313 public static final native int CloseHandle(@JniArg(cast="HANDLE")long handle); 314 315 316 /** 317 * see: http://msdn.microsoft.com/en-us/library/ms679360(VS.85).aspx 318 * 319 * @param handle 320 * @return 321 */ 322 public static final native int GetLastError(); 323 324 /** 325 * 326 * @param flags 327 * @param source 328 * @param messageId 329 * @param languageId 330 * @param buffer 331 * @param size 332 * @param arguments 333 * @return 334 */ 335 public static final native int FormatMessageW( 336 int flags, 337 @JniArg(cast="void *")long source, 338 int messageId, 339 int languageId, 340 @JniArg(cast="void *", flags={NO_IN, CRITICAL})byte[] buffer, 341 int size, 342 @JniArg(cast="void *", flags={NO_IN, CRITICAL, SENTINEL})long []args 343 ); 344 345 346 /** 347 * See: http://msdn.microsoft.com/en-us/library/ms683171%28VS.85%29.aspx 348 * @param consoleOutput 349 * @param consoleScreenBufferInfo 350 * @return 351 */ 352 public static final native int GetConsoleScreenBufferInfo( 353 @JniArg(cast="HANDLE", flags={POINTER_ARG})long consoleOutput, 354 CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo); 355 356 /** 357 * see: http://msdn.microsoft.com/en-us/library/ms683231%28VS.85%29.aspx 358 * @param stdHandle 359 * @return 360 */ 361 @JniMethod(cast="HANDLE", flags={POINTER_RETURN}) 362 public static final native long GetStdHandle(int stdHandle); 363 364 /** 365 * http://msdn.microsoft.com/en-us/library/ms686025%28VS.85%29.aspx 366 * @param consoleOutput 367 * @param cursorPosition 368 * @return 369 */ 370 public static final native int SetConsoleCursorPosition( 371 @JniArg(cast="HANDLE", flags={POINTER_ARG})long consoleOutput, 372 @JniArg(flags={BY_VALUE}) COORD cursorPosition); 373 374 /** 375 * see: http://msdn.microsoft.com/en-us/library/ms682663%28VS.85%29.aspx 376 * 377 * @param consoleOutput 378 * @param character 379 * @param length 380 * @param dwWriteCoord 381 * @param numberOfCharsWritten 382 * @return 383 */ 384 public static final native int FillConsoleOutputCharacterW( 385 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long consoleOutput, 386 char character, 387 int length, 388 @JniArg(flags={BY_VALUE}) COORD writeCoord, 389 int[] numberOfCharsWritten); 390 391 392 /** 393 * see: http://msdn.microsoft.com/en-us/library/ms683167%28VS.85%29.aspx 394 * @param handle 395 * @param mode 396 * @return 397 */ 398 public static final native int GetConsoleMode( 399 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 400 int[] mode); 401 402 /** 403 * see: http://msdn.microsoft.com/en-us/library/ms686033%28VS.85%29.aspx 404 * @param handle 405 * @param mode 406 * @return 407 */ 408 public static final native int SetConsoleMode( 409 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 410 int mode); 411 412 /** 413 * see: http://msdn.microsoft.com/en-us/library/078sfkak(VS.80).aspx 414 * @return 415 */ 416 public static final native int _getch(); 417 418 419 /** 420 * see: http://msdn.microsoft.com/en-us/library/ms686050%28VS.85%29.aspx 421 * @param title 422 * @return 0 if title was set successfully 423 */ 424 public static final native int SetConsoleTitle( 425 @JniArg(flags={UNICODE}) String title); 426 427 /** 428 * see: http://msdn.microsoft.com/en-us/library/ms684166(v=VS.85).aspx 429 */ 430 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 431 public static class KEY_EVENT_RECORD { 432 433 static { 434 LIBRARY.load(); 435 init(); 436 } 437 438 @JniMethod(flags={CONSTANT_INITIALIZER}) 439 private static final native void init(); 440 @JniField(flags={CONSTANT}, accessor="sizeof(KEY_EVENT_RECORD)") 441 public static int SIZEOF; 442 @JniField(flags={CONSTANT}, accessor="CAPSLOCK_ON") 443 public static int CAPSLOCK_ON; 444 @JniField(flags={CONSTANT}, accessor="NUMLOCK_ON") 445 public static int NUMLOCK_ON; 446 @JniField(flags={CONSTANT}, accessor="SCROLLLOCK_ON") 447 public static int SCROLLLOCK_ON; 448 @JniField(flags={CONSTANT}, accessor="ENHANCED_KEY") 449 public static int ENHANCED_KEY; 450 @JniField(flags={CONSTANT}, accessor="LEFT_ALT_PRESSED") 451 public static int LEFT_ALT_PRESSED; 452 @JniField(flags={CONSTANT}, accessor="LEFT_CTRL_PRESSED") 453 public static int LEFT_CTRL_PRESSED; 454 @JniField(flags={CONSTANT}, accessor="RIGHT_ALT_PRESSED") 455 public static int RIGHT_ALT_PRESSED; 456 @JniField(flags={CONSTANT}, accessor="RIGHT_CTRL_PRESSED") 457 public static int RIGHT_CTRL_PRESSED; 458 @JniField(flags={CONSTANT}, accessor="SHIFT_PRESSED") 459 public static int SHIFT_PRESSED; 460 461 @JniField(accessor="bKeyDown") 462 public boolean keyDown; 463 @JniField(accessor="wRepeatCount") 464 public short repeatCount; 465 @JniField(accessor="wVirtualKeyCode") 466 public short keyCode; 467 @JniField(accessor="wVirtualScanCode") 468 public short scanCode; 469 @JniField(accessor="uChar.UnicodeChar") 470 public char uchar; 471 @JniField(accessor="dwControlKeyState") 472 public int controlKeyState; 473 474 public String toString() { 475 return "KEY_EVENT_RECORD{" + 476 "keyDown=" + keyDown + 477 ", repeatCount=" + repeatCount + 478 ", keyCode=" + keyCode + 479 ", scanCode=" + scanCode + 480 ", uchar=" + uchar + 481 ", controlKeyState=" + controlKeyState + 482 '}'; 483 } 484 } 485 486 /** 487 * see: http://msdn.microsoft.com/en-us/library/ms683499(v=VS.85).aspx 488 */ 489 @JniClass(flags={ClassFlag.STRUCT,TYPEDEF}, conditional="defined(_WIN32) || defined(_WIN64)") 490 public static class INPUT_RECORD { 491 492 static { 493 LIBRARY.load(); 494 init(); 495 } 496 497 @JniMethod(flags={CONSTANT_INITIALIZER}) 498 private static final native void init(); 499 @JniField(flags={CONSTANT}, accessor="sizeof(INPUT_RECORD)") 500 public static int SIZEOF; 501 @JniField(flags={CONSTANT}, accessor="KEY_EVENT") 502 public static short KEY_EVENT; 503 504 @JniField(accessor="EventType") 505 public short eventType; 506 @JniField(accessor="Event.KeyEvent") 507 public KEY_EVENT_RECORD keyEvent = new KEY_EVENT_RECORD(); 508 } 509 510 /** 511 * see: http://msdn.microsoft.com/en-us/library/ms684961(v=VS.85).aspx 512 * @param handle 513 * @param length must be exactly 1 514 * @param eventsCount 515 * @return 516 */ 517 private static final native int ReadConsoleInputW( 518 @JniArg(cast="HANDLE", flags={POINTER_ARG}) long handle, 519 INPUT_RECORD inputRecord, 520 int length, // must be one 521 int[] eventsCount); 522 523 /** 524 * Return a key event record (discard other events until a key event is 525 * found) 526 * @param handle 527 * @return null on read errors 528 */ 529 public static KEY_EVENT_RECORD readKeyEvent( 530 long handle) { 531 int[] count = new int[1]; 532 INPUT_RECORD inputRecord = new INPUT_RECORD(); 533 int loop = 0; // give up after some arbitrary threshold 534 int res; 535 while (loop < 1000) { 536 res = ReadConsoleInputW(handle, inputRecord, 1, count); 537 if (res != 0 && count[0] == 1) { 538 if (inputRecord.eventType == INPUT_RECORD.KEY_EVENT) { 539 return inputRecord.keyEvent; 540 } 541 } else { 542 return null; 543 } 544 loop++; 545 } 546 return null; 547 } 548 }