aboutsummaryrefslogtreecommitdiff
path: root/core/sys/win32
diff options
context:
space:
mode:
authorBrendan Punsky <bpunsky@gmail.com>2019-03-13 16:45:46 -0400
committerGitHub <noreply@github.com>2019-03-13 16:45:46 -0400
commiteadb66c9efc19ad1deaee6ca5a141cbd7206fcce (patch)
tree01eb1a33ffba203c45460e0e50da4b5f4ca31076 /core/sys/win32
parent9d7e1c17cc4a9b0d6cfd4c741c800b5732eb9948 (diff)
parentbdab5e00da6dee80b7582135815f2183def935bb (diff)
Merge branch 'master' into master
Diffstat (limited to 'core/sys/win32')
-rw-r--r--core/sys/win32/comdlg32.odin100
-rw-r--r--core/sys/win32/crt.odin14
-rw-r--r--core/sys/win32/general.odin3
-rw-r--r--core/sys/win32/kernel32.odin47
4 files changed, 159 insertions, 5 deletions
diff --git a/core/sys/win32/comdlg32.odin b/core/sys/win32/comdlg32.odin
index 790c9d598..3d9fb74c4 100644
--- a/core/sys/win32/comdlg32.odin
+++ b/core/sys/win32/comdlg32.odin
@@ -2,6 +2,7 @@
package win32
foreign import "system:comdlg32.lib"
+import "core:strings"
OFN_Hook_Proc :: #type proc "stdcall" (hdlg: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Uint_Ptr;
@@ -61,11 +62,91 @@ Open_File_Name_W :: struct {
foreign comdlg32 {
@(link_name="GetOpenFileNameA") get_open_file_name_a :: proc(arg1: ^Open_File_Name_A) -> Bool ---
@(link_name="GetOpenFileNameW") get_open_file_name_w :: proc(arg1: ^Open_File_Name_W) -> Bool ---
-
+ @(link_name="GetSaveFileNameA") get_save_file_name_a :: proc(arg1: ^Open_File_Name_A) -> Bool ---
+ @(link_name="GetSaveFileNameW") get_save_file_name_w :: proc(arg1: ^Open_File_Name_W) -> Bool ---
@(link_name="CommDlgExtendedError") comm_dlg_extended_error :: proc() -> u32 ---
}
-OFN_ALLOWMULTISELECT :: 0x00000200;
+OPEN_TITLE :: "Select file to open";
+OPEN_FLAGS :: u32(OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST);
+OPEN_FLAGS_MULTI :: u32(OPEN_FLAGS | OFN_ALLOWMULTISELECT | OFN_EXPLORER);
+
+SAVE_TITLE :: "Select file to save";
+SAVE_FLAGS :: u32(OFN_OVERWRITEPROMPT | OFN_EXPLORER);
+SAVE_EXT :: "txt";
+
+Open_Save_Mode :: enum {
+ Open = 0,
+ Save = 1,
+}
+
+_open_file_dialog :: proc(title: string, dir: string,
+ filters: []string, default_filter: u32,
+ flags: u32, default_ext: string,
+ mode: Open_Save_Mode, allocator := context.temp_allocator) -> (path: string, ok: bool = true) {
+ file_buf := make([]u16, MAX_PATH_WIDE, allocator);
+
+ // Filters need to be passed as a pair of strings (title, filter)
+ filter_len := u32(len(filters));
+ if filter_len % 2 != 0 do return "", false;
+ default_filter = clamp(default_filter, 1, filter_len / 2);
+
+ filter: string;
+ filter = strings.join(filters, "\u0000", context.temp_allocator);
+ filter = strings.concatenate({filter, "\u0000"}, context.temp_allocator);
+
+ ofn := Open_File_Name_W{
+ struct_size = size_of(Open_File_Name_W),
+ file = Wstring(&file_buf[0]),
+ max_file = MAX_PATH_WIDE,
+ title = utf8_to_wstring(title, context.temp_allocator),
+ filter = utf8_to_wstring(filter, context.temp_allocator),
+ initial_dir = utf8_to_wstring(dir, context.temp_allocator),
+ filter_index = u32(default_filter),
+ def_ext = utf8_to_wstring(default_ext, context.temp_allocator),
+ flags = u32(flags),
+ };
+
+ switch mode {
+ case .Open:
+ ok = bool(get_open_file_name_w(&ofn));
+ case .Save:
+ ok = bool(get_save_file_name_w(&ofn));
+ case:
+ ok = false;
+ }
+
+ if !ok {
+ delete(file_buf);
+ return "", false;
+ }
+
+ file_name := ucs2_to_utf8(file_buf[:], allocator);
+ path = strings.trim_right_null(file_name);
+ return;
+}
+
+select_file_to_open :: proc(title := OPEN_TITLE, dir := ".",
+ filters := []string{"All Files", "*.*"}, default_filter := u32(1),
+ flags := OPEN_FLAGS, allocator := context.temp_allocator) -> (path: string, ok: bool) {
+
+ path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, "", Open_Save_Mode.Open, allocator);
+ return;
+}
+
+select_file_to_save :: proc(title := SAVE_TITLE, dir := ".",
+ filters := []string{"All Files", "*.*"}, default_filter := u32(1),
+ flags := SAVE_FLAGS, default_ext := SAVE_EXT,
+ allocator := context.temp_allocator) -> (path: string, ok: bool) {
+
+ path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, default_ext, Open_Save_Mode.Save, allocator);
+ return;
+}
+
+// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes
+// it output of the form "path\u0000\file1u\0000file2" and turns it into []string with the path + file pre-concatenated for you.
+
+OFN_ALLOWMULTISELECT :: 0x00000200; // NOTE(Jeroen): Without OFN_EXPLORER it uses the Win3 dialog.
OFN_CREATEPROMPT :: 0x00002000;
OFN_DONTADDTORECENT :: 0x02000000;
OFN_ENABLEHOOK :: 0x00000020;
@@ -91,3 +172,18 @@ OFN_PATHMUSTEXIST :: 0x00000800;
OFN_READONLY :: 0x00000001;
OFN_SHAREAWARE :: 0x00004000;
OFN_SHOWHELP :: 0x00000010;
+
+CDERR_DIALOGFAILURE :: 0x0000FFFF;
+CDERR_GENERALCODES :: 0x00000000;
+CDERR_STRUCTSIZE :: 0x00000001;
+CDERR_INITIALIZATION :: 0x00000002;
+CDERR_NOTEMPLATE :: 0x00000003;
+CDERR_NOHINSTANCE :: 0x00000004;
+CDERR_LOADSTRFAILURE :: 0x00000005;
+CDERR_FINDRESFAILURE :: 0x00000006;
+CDERR_LOADRESFAILURE :: 0x00000007;
+CDERR_LOCKRESFAILURE :: 0x00000008;
+CDERR_MEMALLOCFAILURE :: 0x00000009;
+CDERR_MEMLOCKFAILURE :: 0x0000000A;
+CDERR_NOHOOK :: 0x0000000B;
+CDERR_REGISTERMSGFAIL :: 0x0000000C; \ No newline at end of file
diff --git a/core/sys/win32/crt.odin b/core/sys/win32/crt.odin
new file mode 100644
index 000000000..46fba6fe8
--- /dev/null
+++ b/core/sys/win32/crt.odin
@@ -0,0 +1,14 @@
+package win32
+
+import "core:strings";
+
+foreign {
+ @(link_name="_wgetcwd") _get_cwd_wide :: proc(buffer: Wstring, buf_len: int) -> ^Wstring ---
+}
+
+get_cwd :: proc(allocator := context.temp_allocator) -> string {
+ buffer := make([]u16, MAX_PATH_WIDE, allocator);
+ _get_cwd_wide(Wstring(&buffer[0]), MAX_PATH_WIDE);
+ file := ucs2_to_utf8(buffer[:], allocator);
+ return strings.trim_right_null(file);
+} \ No newline at end of file
diff --git a/core/sys/win32/general.odin b/core/sys/win32/general.odin
index c34294b51..f4f3de380 100644
--- a/core/sys/win32/general.odin
+++ b/core/sys/win32/general.odin
@@ -108,6 +108,8 @@ File_Attribute_Data :: struct {
file_size_low: u32,
}
+// NOTE(Jeroen): The widechar version might want at least the 32k MAX_PATH_WIDE
+// https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findfirstfilew#parameters
Find_Data_W :: struct{
file_attributes: u32,
creation_time: Filetime,
@@ -798,6 +800,7 @@ is_key_down :: inline proc(key: Key_Code) -> bool { return get_async_key_state(i
MAX_PATH :: 0x00000104;
+MAX_PATH_WIDE :: 0x8000;
HANDLE_FLAG_INHERIT :: 1;
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin
index 56a150a5c..6e9c752fb 100644
--- a/core/sys/win32/kernel32.odin
+++ b/core/sys/win32/kernel32.odin
@@ -56,8 +56,8 @@ foreign kernel32 {
@(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool ---;
@(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: cstring) -> u32 ---;
@(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: Wstring) -> u32 ---;
- @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: cstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---;
- @(link_name="GetFileAttributesExW") get_file_attributes_ex_w :: proc(filename: Wstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---;
+ @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: cstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: ^File_Attribute_Data) -> Bool ---;
+ @(link_name="GetFileAttributesExW") get_file_attributes_ex_w :: proc(filename: Wstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: ^File_Attribute_Data) -> Bool ---;
@(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool ---;
@(link_name="CreateDirectoryA") create_directory_a :: proc(path: cstring, security_attributes: ^Security_Attributes) -> Bool ---;
@@ -164,7 +164,7 @@ foreign kernel32 {
@(link_name="LoadLibraryA") load_library_a :: proc(c_str: cstring) -> Hmodule ---;
@(link_name="LoadLibraryW") load_library_w :: proc(c_str: Wstring) -> Hmodule ---;
- @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) ---;
+ @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) -> Bool ---;
@(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: cstring) -> rawptr ---;
@(link_name="GetFullPathNameA") get_full_path_name_a :: proc(filename: cstring, buffer_length: u32, buffer: cstring, file_part: ^Wstring) -> u32 ---;
@@ -177,3 +177,44 @@ foreign kernel32 {
@(link_name="GetCurrentDirectorya") get_current_directory_a :: proc(buffer_length: u32, buffer: cstring) -> u32 ---;
@(link_name="GetCurrentDirectoryW") get_current_directory_w :: proc(buffer_length: u32, buffer: Wstring) -> u32 ---;
}
+
+Memory_Basic_Information :: struct {
+ base_address: rawptr,
+ allocation_base: rawptr,
+ allocation_protect: u32,
+ region_size: uint,
+ state: u32,
+ protect: u32,
+ type: u32,
+}
+
+@(default_calling_convention = "std")
+foreign kernel32 {
+ @(link_name="VirtualAlloc") virtual_alloc :: proc(address: rawptr, size: uint, allocation_type: u32, protect: u32) -> rawptr ---
+ @(link_name="VirtualAllocEx") virtual_alloc_ex :: proc(process: Handle, address: rawptr, size: uint, allocation_type: u32, protect: u32) -> rawptr ---
+ @(link_name="VirtualFree") virtual_free :: proc(address: rawptr, size: uint, free_type: u32) -> Bool ---
+ @(link_name="VirtualLock") virtual_lock :: proc(address: rawptr, size: uint) -> Bool ---
+ @(link_name="VirtualProtect") virtual_protect :: proc(address: rawptr, size: uint, new_protect: u32, old_protect: ^u32) -> Bool ---
+ @(link_name="VirtualQuery") virtual_query :: proc(address: rawptr, buffer: ^Memory_Basic_Information, length: uint) -> uint ---
+}
+
+MEM_COMMIT :: 0x00001000;
+MEM_RESERVE :: 0x00002000;
+MEM_DECOMMIT :: 0x00004000;
+MEM_RELEASE :: 0x00008000;
+MEM_RESET :: 0x00080000;
+MEM_RESET_UNDO :: 0x01000000;
+
+MEM_LARGE_PAGES :: 0x20000000;
+MEM_PHYSICAL :: 0x00400000;
+MEM_TOP_DOWN :: 0x00100000;
+MEM_WRITE_WATCH :: 0x00200000;
+
+PAGE_NOACCESS :: 0x01;
+PAGE_READONLY :: 0x02;
+PAGE_READWRITE :: 0x04;
+PAGE_WRITECOPY :: 0x08;
+PAGE_EXECUTE :: 0x10;
+PAGE_EXECUTE_READ :: 0x20;
+PAGE_EXECUTE_READWRITE :: 0x40;
+PAGE_EXECUTE_WRITECOPY :: 0x80;