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 }