Skip to content

Commit

Permalink
Disable raw mode on windows nativeimage
Browse files Browse the repository at this point in the history
  • Loading branch information
ajalt committed Jun 16, 2024
1 parent e4d97be commit 23c9ba4
Showing 1 changed file with 150 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ private object WinKernel32Lib {
@CConstant("STD_ERROR_HANDLE")
external fun STD_ERROR_HANDLE(): Int

@CConstant("ENABLE_PROCESSED_INPUT")
external fun ENABLE_PROCESSED_INPUT(): Int
// @CConstant("ENABLE_PROCESSED_INPUT")
// external fun ENABLE_PROCESSED_INPUT(): Int

@CStruct("CONSOLE_SCREEN_BUFFER_INFO")
interface CONSOLE_SCREEN_BUFFER_INFO : PointerBase {
Expand All @@ -52,86 +52,86 @@ private object WinKernel32Lib {

}

@CStruct("uChar")
interface UnionChar : PointerBase {
@get:CFieldAddress("UnicodeChar")
val UnicodeChar: Char

@get:CFieldAddress("AsciiChar")
val AsciiChar: Byte
}

@CStruct("COORD")
interface COORD : PointerBase {
@get:CField("X")
var X: Short

@get:CField("Y")
var Y: Short
}

@CStruct("KEY_EVENT_RECORD")
interface KEY_EVENT_RECORD : PointerBase {
@get:CField("bKeyDown")
val bKeyDown: Boolean

@get:CField("wRepeatCount")
val wRepeatCount: Short

@get:CField("wVirtualKeyCode")
val wVirtualKeyCode: Short

@get:CField("wVirtualScanCode")
val wVirtualScanCode: Short

@get:CField("uChar")
val uChar: UnionChar?

@get:CField("dwControlKeyState")
val dwControlKeyState: Int
}

@CStruct("MOUSE_EVENT_RECORD")
interface MOUSE_EVENT_RECORD : PointerBase {
@get:CField("dwMousePosition")
var dwMousePosition: COORD

@get:CField("dwButtonState")
var dwButtonState: Int

@get:CField("dwControlKeyState")
var dwControlKeyState: Int

@get:CField("dwEventFlags")
var dwEventFlags: Int
}

@CStruct("Event")
interface EventUnion : PointerBase {
@get:CFieldAddress("KeyEvent")
val KeyEvent: KEY_EVENT_RECORD

@get:CFieldAddress("MouseEvent")
val MouseEvent: MOUSE_EVENT_RECORD
// ... other fields omitted until we need them
}

@CStruct("INPUT_RECORD")
interface INPUT_RECORD : PointerBase {
companion object {
const val KEY_EVENT: Short = 0x0001
const val MOUSE_EVENT: Short = 0x0002
const val WINDOW_BUFFER_SIZE_EVENT: Short = 0x0004
const val MENU_EVENT: Short = 0x0008
const val FOCUS_EVENT: Short = 0x0010
}

@get:CField("EventType")
val EventType: Short

@get:CField("Event")
val Event: EventUnion
}
// @CStruct("uChar")
// interface UnionChar : PointerBase {
// @get:CFieldAddress("UnicodeChar")
// val UnicodeChar: Char
//
// @get:CFieldAddress("AsciiChar")
// val AsciiChar: Byte
// }
//
// @CStruct("COORD")
// interface COORD : PointerBase {
// @get:CField("X")
// var X: Short
//
// @get:CField("Y")
// var Y: Short
// }
//
// @CStruct("KEY_EVENT_RECORD")
// interface KEY_EVENT_RECORD : PointerBase {
// @get:CField("bKeyDown")
// val bKeyDown: Boolean
//
// @get:CField("wRepeatCount")
// val wRepeatCount: Short
//
// @get:CField("wVirtualKeyCode")
// val wVirtualKeyCode: Short
//
// @get:CField("wVirtualScanCode")
// val wVirtualScanCode: Short
//
// @get:CField("uChar")
// val uChar: UnionChar?
//
// @get:CField("dwControlKeyState")
// val dwControlKeyState: Int
// }
//
// @CStruct("MOUSE_EVENT_RECORD")
// interface MOUSE_EVENT_RECORD : PointerBase {
// @get:CField("dwMousePosition")
// var dwMousePosition: COORD
//
// @get:CField("dwButtonState")
// var dwButtonState: Int
//
// @get:CField("dwControlKeyState")
// var dwControlKeyState: Int
//
// @get:CField("dwEventFlags")
// var dwEventFlags: Int
// }
//
// @CStruct("Event")
// interface EventUnion : PointerBase {
// @get:CFieldAddress("KeyEvent")
// val KeyEvent: KEY_EVENT_RECORD
//
// @get:CFieldAddress("MouseEvent")
// val MouseEvent: MOUSE_EVENT_RECORD
// // ... other fields omitted until we need them
// }
//
// @CStruct("INPUT_RECORD")
// interface INPUT_RECORD : PointerBase {
// companion object {
// const val KEY_EVENT: Short = 0x0001
// const val MOUSE_EVENT: Short = 0x0002
// const val WINDOW_BUFFER_SIZE_EVENT: Short = 0x0004
// const val MENU_EVENT: Short = 0x0008
// const val FOCUS_EVENT: Short = 0x0010
// }
//
// @get:CField("EventType")
// val EventType: Short
//
// @get:CField("Event")
// val Event: EventUnion
// }


@CFunction("GetStdHandle")
Expand All @@ -148,17 +148,17 @@ private object WinKernel32Lib {
hConsoleOutput: PointerBase?,
lpConsoleScreenBufferInfo: Long,
): Boolean

@CFunction("WaitForSingleObject")
external fun WaitForSingleObject(hHandle: PointerBase?, dwMilliseconds: Int): Int

@CFunction("ReadConsoleInput")
external fun ReadConsoleInput(
hConsoleOutput: PointerBase?,
lpBuffer: INPUT_RECORD,
nLength: Int,
lpNumberOfEventsRead: CIntPointer?,
)
//
// @CFunction("WaitForSingleObject")
// external fun WaitForSingleObject(hHandle: PointerBase?, dwMilliseconds: Int): Int
//
// @CFunction("ReadConsoleInput")
// external fun ReadConsoleInput(
// hConsoleOutput: PointerBase?,
// lpBuffer: INPUT_RECORD,
// nLength: Int,
// lpNumberOfEventsRead: CIntPointer?,
// )
}

@Platforms(Platform.WINDOWS::class)
Expand Down Expand Up @@ -190,58 +190,68 @@ internal class SyscallHandlerNativeImageWindows : SyscallHandlerWindows() {
}

override fun getStdinConsoleMode(): UInt {
val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
val lpMode = StackValue.get(CIntPointer::class.java)
if (!WinKernel32Lib.GetConsoleMode(stdinHandle, lpMode)) {
throw RuntimeException("Error reading console mode")
}
return lpMode.read().toUInt()
throw NotImplementedError(
"Raw mode is not currently supported for native-image. If you are familiar with " +
"GraalVM native-image and would like to contribute, see the commented out " +
"code in the file SyscallHandler.nativeimage.posix"
)
// val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
// val lpMode = StackValue.get(CIntPointer::class.java)
// if (!WinKernel32Lib.GetConsoleMode(stdinHandle, lpMode)) {
// throw RuntimeException("Error reading console mode")
// }
// return lpMode.read().toUInt()
}

override fun setStdinConsoleMode(dwMode: UInt) {
val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
if (!WinKernel32Lib.SetConsoleMode(stdinHandle, WinKernel32Lib.ENABLE_PROCESSED_INPUT())) {
throw RuntimeException("Error setting console mode")
}
// val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
// if (!WinKernel32Lib.SetConsoleMode(stdinHandle, WinKernel32Lib.ENABLE_PROCESSED_INPUT())) {
// throw RuntimeException("Error setting console mode")
// }
}

override fun readRawEvent(dwMilliseconds: Int): EventRecord {
val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
val waitResult = WinKernel32Lib.WaitForSingleObject(stdinHandle, dwMilliseconds)
if (waitResult != 0) {
throw RuntimeException("Error reading from console input: waitResult=$waitResult")
}
val inputEvents = StackValue.get(WinKernel32Lib.INPUT_RECORD::class.java)
val eventsRead = StackValue.get(CIntPointer::class.java)
WinKernel32Lib.ReadConsoleInput(stdinHandle, inputEvents, 1, eventsRead)
if (eventsRead.read() == 0) {
throw RuntimeException("Error reading from console input")
}
return when (inputEvents.EventType) {
WinKernel32Lib.INPUT_RECORD.KEY_EVENT -> {
val keyEvent = inputEvents.Event.KeyEvent
EventRecord.Key(
bKeyDown = keyEvent.bKeyDown,
wVirtualKeyCode = keyEvent.wVirtualKeyCode.toUShort(),
uChar = keyEvent.uChar!!.UnicodeChar,
dwControlKeyState = keyEvent.dwControlKeyState.toUInt(),
)
}

WinKernel32Lib.INPUT_RECORD.MOUSE_EVENT -> {
val mouseEvent = inputEvents.Event.MouseEvent
EventRecord.Mouse(
dwMousePositionX = mouseEvent.dwMousePosition.X,
dwMousePositionY = mouseEvent.dwMousePosition.Y,
dwButtonState = mouseEvent.dwButtonState.toUInt(),
dwControlKeyState = mouseEvent.dwControlKeyState.toUInt(),
dwEventFlags = mouseEvent.dwEventFlags.toUInt(),
)
}

else -> throw RuntimeException(
"Error reading from console input: unexpected event type ${inputEvents.EventType}"
)
}
throw NotImplementedError(
"Raw mode is not currently supported for native-image. If you are familiar with " +
"GraalVM native-image and would like to contribute, see the commented out " +
"code in the file SyscallHandler.nativeimage.posix"
)
// val stdinHandle = WinKernel32Lib.GetStdHandle(WinKernel32Lib.STD_INPUT_HANDLE())
// val waitResult = WinKernel32Lib.WaitForSingleObject(stdinHandle, dwMilliseconds)
// if (waitResult != 0) {
// throw RuntimeException("Error reading from console input: waitResult=$waitResult")
// }
// val inputEvents = StackValue.get(WinKernel32Lib.INPUT_RECORD::class.java)
// val eventsRead = StackValue.get(CIntPointer::class.java)
// WinKernel32Lib.ReadConsoleInput(stdinHandle, inputEvents, 1, eventsRead)
// if (eventsRead.read() == 0) {
// throw RuntimeException("Error reading from console input")
// }
// return when (inputEvents.EventType) {
// WinKernel32Lib.INPUT_RECORD.KEY_EVENT -> {
// val keyEvent = inputEvents.Event.KeyEvent
// EventRecord.Key(
// bKeyDown = keyEvent.bKeyDown,
// wVirtualKeyCode = keyEvent.wVirtualKeyCode.toUShort(),
// uChar = keyEvent.uChar!!.UnicodeChar,
// dwControlKeyState = keyEvent.dwControlKeyState.toUInt(),
// )
// }
//
// WinKernel32Lib.INPUT_RECORD.MOUSE_EVENT -> {
// val mouseEvent = inputEvents.Event.MouseEvent
// EventRecord.Mouse(
// dwMousePositionX = mouseEvent.dwMousePosition.X,
// dwMousePositionY = mouseEvent.dwMousePosition.Y,
// dwButtonState = mouseEvent.dwButtonState.toUInt(),
// dwControlKeyState = mouseEvent.dwControlKeyState.toUInt(),
// dwEventFlags = mouseEvent.dwEventFlags.toUInt(),
// )
// }
//
// else -> throw RuntimeException(
// "Error reading from console input: unexpected event type ${inputEvents.EventType}"
// )
// }
}
}

0 comments on commit 23c9ba4

Please sign in to comment.