From ffc592c7cfd61425b3377ea0ac544c8117732046 Mon Sep 17 00:00:00 2001 From: Jeppe Skov Date: Tue, 28 Feb 2023 23:17:00 +0100 Subject: [PATCH 1/2] Added missing Windows functions for console manipulation This commit adds several missing types and functions to the Windows implementation to enable manipulation of console windows. The types added include 'SMALL_RECT', 'CONSOLE_SCREEN_BUFFER_INFO', and 'PCONSOLE_SCREEN_BUFFER_INFO'. The functions added include 'GetConsoleScreenBufferInfo', 'SetConsoleScreenBufferSize', and 'SetConsoleWindowInfo'. These functions were necessary to properly manage the console window. --- core/sys/windows/kernel32.odin | 3 +++ core/sys/windows/types.odin | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index f736696e1..5f09dda3c 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -370,6 +370,9 @@ foreign kernel32 { GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL --- FreeConsole :: proc() -> BOOL --- GetConsoleWindow :: proc() -> HWND --- + GetConsoleScreenBufferInfo :: proc(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO) -> BOOL --- + SetConsoleScreenBufferSize :: proc(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL --- + SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute : BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL --- GetDiskFreeSpaceExW :: proc( lpDirectoryName: LPCWSTR, diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 1d5bdaf04..10a2e20a7 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -3884,3 +3884,21 @@ COORD :: struct { X: SHORT, Y: SHORT, } + +SMALL_RECT :: struct { + Left: SHORT, + Top: SHORT, + Right: SHORT, + Bottom: SHORT, +} + +CONSOLE_SCREEN_BUFFER_INFO :: struct { + dwSize: COORD, + dwCursorPosition: COORD, + wAttributes: WORD, + srWindow: SMALL_RECT, + dwMaximumWindowSize: COORD, +} + + +PCONSOLE_SCREEN_BUFFER_INFO :: ^CONSOLE_SCREEN_BUFFER_INFO \ No newline at end of file From bb72c804fb6256caf074f6e1c9aa1d42c231b4d6 Mon Sep 17 00:00:00 2001 From: Lucas Perlind Date: Thu, 2 Mar 2023 18:28:29 +1100 Subject: [PATCH 2/2] Document core:dynlib --- core/dynlib/doc.odin | 7 ++++ core/dynlib/lib.odin | 83 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 core/dynlib/doc.odin diff --git a/core/dynlib/doc.odin b/core/dynlib/doc.odin new file mode 100644 index 000000000..812fb02d5 --- /dev/null +++ b/core/dynlib/doc.odin @@ -0,0 +1,7 @@ +/* +Package core:dynlib implements loading of shared libraries/DLLs and their symbols. + +The behaviour of dynamically loaded libraries is specific to the target platform of the program. +For in depth detail on the underlying behaviour please refer to your target platform's documentation. +*/ +package dynlib diff --git a/core/dynlib/lib.odin b/core/dynlib/lib.odin index a6c857ee4..b5cb16e3c 100644 --- a/core/dynlib/lib.odin +++ b/core/dynlib/lib.odin @@ -1,15 +1,94 @@ package dynlib +/* +A handle to a dynamically loaded library. +*/ Library :: distinct rawptr -load_library :: proc(path: string, global_symbols := false) -> (Library, bool) { +/* +Loads a dynamic library from the filesystem. The paramater `global_symbols` makes the symbols in the loaded +library available to resolve references in subsequently loaded libraries. + +The paramater `global_symbols` is only used for the platforms `linux`, `darwin`, `freebsd` and `openbsd`. +On `windows` this paramater is ignored. + +The underlying behaviour is platform specific. +On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlopen`. +On `windows` refer to `LoadLibraryW`. + +**Implicit Allocators** +`context.temp_allocator` + +Example: + import "core:dynlib" + import "core:fmt" + + load_my_library :: proc() { + LIBRARY_PATH :: "my_library.dll" + library, ok := dynlib.load_library(LIBRARY_PATH) + if ! ok { + return + } + fmt.println("The library %q was successfully loaded", LIBRARY_PATH) + } +*/ +load_library :: proc(path: string, global_symbols := false) -> (library: Library, did_load: bool) { return _load_library(path, global_symbols) } -unload_library :: proc(library: Library) -> bool { +/* +Unloads a dynamic library. + +The underlying behaviour is platform specific. +On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlclose`. +On `windows` refer to `FreeLibrary`. + +Example: + import "core:dynlib" + import "core:fmt" + + load_then_unload_my_library :: proc() { + LIBRARY_PATH :: "my_library.dll" + library, ok := dynlib.load_library(LIBRARY_PATH) + if ! ok { + return + } + did_unload := dynlib.unload_library(library) + if ! did_unload { + return + } + fmt.println("The library %q was successfully unloaded", LIBRARY_PATH) + } +*/ +unload_library :: proc(library: Library) -> (did_unload: bool) { return _unload_library(library) } +/* +Loads the address of a procedure/variable from a dynamic library. + +The underlying behaviour is platform specific. +On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlsym`. +On `windows` refer to `GetProcAddress`. + +**Implicit Allocators** +`context.temp_allocator` + +Example: + import "core:dynlib" + import "core:fmt" + + find_a_in_my_library :: proc() { + LIBRARY_PATH :: "my_library.dll" + library, ok := dynlib.load_library(LIBRARY_PATH) + if ! ok { + return + } + + a, found_a := dynlib.symbol_address(library, "a") + if found_a do fmt.printf("The symbol %q was found at the address %v", "a", a) + } +*/ symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) #optional_ok { return _symbol_address(library, symbol) }