diff --git a/core/sys/windows/bluetooth.odin b/core/sys/windows/bluetooth.odin index c9f6bcc93..dad44892a 100644 --- a/core/sys/windows/bluetooth.odin +++ b/core/sys/windows/bluetooth.odin @@ -51,7 +51,7 @@ BLUETOOTH_DEVICE_INFO :: struct { name: [BLUETOOTH_MAX_NAME_SIZE]u16, // Name of the device } -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign bthprops { /* Version diff --git a/core/sys/windows/comdlg32.odin b/core/sys/windows/comdlg32.odin new file mode 100644 index 000000000..a3709cba7 --- /dev/null +++ b/core/sys/windows/comdlg32.odin @@ -0,0 +1,168 @@ +// +build windows +package sys_windows + +foreign import "system:Comdlg32.lib" +import "core:strings" + +LPOFNHOOKPROC :: #type proc "stdcall" (hdlg: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR + +OPENFILENAMEW :: struct { + lStructSize: DWORD, + hwndOwner: HWND, + hInstance: HINSTANCE, + lpstrFilter: wstring, + lpstrCustomFilter: wstring, + nMaxCustFilter: DWORD, + nFilterIndex: DWORD, + lpstrFile: wstring, + nMaxFile: DWORD, + lpstrFileTitle: wstring, + nMaxFileTitle: DWORD, + lpstrInitialDir: wstring, + lpstrTitle: wstring, + Flags: DWORD, + nFileOffset: WORD, + nFileExtension: WORD, + lpstrDefExt: wstring, + lCustData: LPARAM, + lpfnHook: LPOFNHOOKPROC, + lpTemplateName: wstring, + lpEditInfo: rawptr, // LPEDITMENU, + lpstrPrompt: wstring, + pvReserved: rawptr, + dwReserved: DWORD, + FlagsEx: DWORD, +} + +@(default_calling_convention="stdcall") +foreign Comdlg32 { + GetOpenFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL --- + GetSaveFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL --- + CommDlgExtendedError :: proc() -> u32 --- +} + +OPEN_TITLE :: "Select file to open" +OPEN_FLAGS :: u32(OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST) +OPEN_FLAGS_MULTI :: 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) { + context.allocator = allocator + file_buf := make([]u16, MAX_PATH_WIDE) + defer if !ok { + delete(file_buf) + } + + // Filters need to be passed as a pair of strings (title, filter) + filter_len := u32(len(filters)) + if filter_len % 2 != 0 { + return "", false + } + + filter: string + filter = strings.join(filters, "\u0000", context.temp_allocator) + filter = strings.concatenate({filter, "\u0000"}, context.temp_allocator) + + ofn := OPENFILENAMEW{ + lStructSize = size_of(OPENFILENAMEW), + lpstrFile = wstring(&file_buf[0]), + nMaxFile = MAX_PATH_WIDE, + lpstrTitle = utf8_to_wstring(title, context.temp_allocator), + lpstrFilter = utf8_to_wstring(filter, context.temp_allocator), + lpstrInitialDir = utf8_to_wstring(dir, context.temp_allocator), + nFilterIndex = u32(clamp(default_filter, 1, filter_len / 2)), + lpstrDefExt = utf8_to_wstring(default_ext, context.temp_allocator), + Flags = u32(flags), + } + + switch mode { + case .Open: + ok = bool(GetOpenFileNameW(&ofn)) + case .Save: + ok = bool(GetSaveFileNameW(&ofn)) + case: + ok = false + } + + if !ok { + return + } + + + file_name, _ := utf16_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 +OFN_ENABLEINCLUDENOTIFY :: 0x00400000 +OFN_ENABLESIZING :: 0x00800000 +OFN_ENABLETEMPLATE :: 0x00000040 +OFN_ENABLETEMPLATEHANDLE :: 0x00000080 +OFN_EXPLORER :: 0x00080000 +OFN_EXTENSIONDIFFERENT :: 0x00000400 +OFN_FILEMUSTEXIST :: 0x00001000 +OFN_FORCESHOWHIDDEN :: 0x10000000 +OFN_HIDEREADONLY :: 0x00000004 +OFN_LONGNAMES :: 0x00200000 +OFN_NOCHANGEDIR :: 0x00000008 +OFN_NODEREFERENCELINKS :: 0x00100000 +OFN_NOLONGNAMES :: 0x00040000 +OFN_NONETWORKBUTTON :: 0x00020000 +OFN_NOREADONLYRETURN :: 0x00008000 +OFN_NOTESTFILECREATE :: 0x00010000 +OFN_NOVALIDATE :: 0x00000100 +OFN_OVERWRITEPROMPT :: 0x00000002 +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 diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index ac959db2d..e235b45ed 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -3,8 +3,6 @@ package sys_windows foreign import kernel32 "system:Kernel32.lib" - - @(default_calling_convention="stdcall") foreign kernel32 { OutputDebugStringA :: proc(lpOutputString: LPCSTR) --- @@ -781,7 +779,7 @@ foreign kernel32 { ) -> BOOL --- } -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign kernel32 { @(link_name="SetConsoleCtrlHandler") set_console_ctrl_handler :: proc(handler: Handler_Routine, add: BOOL) -> BOOL --- } diff --git a/core/sys/windows/ntdll.odin b/core/sys/windows/ntdll.odin index 5deffd9f9..dda5b9711 100644 --- a/core/sys/windows/ntdll.odin +++ b/core/sys/windows/ntdll.odin @@ -3,7 +3,7 @@ package sys_windows foreign import ntdll_lib "system:ntdll.lib" -@(default_calling_convention="std") +@(default_calling_convention="stdcall") foreign ntdll_lib { - RtlGetVersion :: proc(lpVersionInformation: ^OSVERSIONINFOEXW) -> NTSTATUS --- + RtlGetVersion :: proc(lpVersionInformation: ^OSVERSIONINFOEXW) -> NTSTATUS --- } \ No newline at end of file diff --git a/core/sys/windows/shell32.odin b/core/sys/windows/shell32.odin index 70d8943bd..a6ecefc32 100644 --- a/core/sys/windows/shell32.odin +++ b/core/sys/windows/shell32.odin @@ -3,7 +3,7 @@ package sys_windows foreign import shell32 "system:Shell32.lib" -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign shell32 { CommandLineToArgvW :: proc(cmd_list: wstring, num_args: ^c_int) -> ^wstring --- } diff --git a/core/sys/windows/wgl.odin b/core/sys/windows/wgl.odin new file mode 100644 index 000000000..689a41dea --- /dev/null +++ b/core/sys/windows/wgl.odin @@ -0,0 +1,87 @@ +// +build windows +package sys_windows + +import "core:c" + +foreign import "system:Opengl32.lib" + +CONTEXT_MAJOR_VERSION_ARB :: 0x2091 +CONTEXT_MINOR_VERSION_ARB :: 0x2092 +CONTEXT_FLAGS_ARB :: 0x2094 +CONTEXT_PROFILE_MASK_ARB :: 0x9126 +CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002 +CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001 +CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002 + +HGLRC :: distinct HANDLE + +LPLAYERPLANEDESCRIPTOR :: ^LAYERPLANEDESCRIPTOR +LAYERPLANEDESCRIPTOR :: struct { + nSize: WORD, + nVersion: WORD, + dwFlags: DWORD, + iPixelType: BYTE, + cColorBits: BYTE, + cRedBits: BYTE, + cRedShift: BYTE, + cGreenBits: BYTE, + cGreenShift: BYTE, + cBlueBits: BYTE, + cBlueShift: BYTE, + cAlphaBits: BYTE, + cAlphaShift: BYTE, + cAccumBits: BYTE, + cAccumRedBits: BYTE, + cAccumGreenBits: BYTE, + cAccumBlueBits: BYTE, + cAccumAlphaBits: BYTE, + cDepthBits: BYTE, + cStencilBits: BYTE, + cAuxBuffers: BYTE, + iLayerPlane: BYTE, + bReserved: BYTE, + crTransparent: COLORREF, +} + +POINTFLOAT :: struct {x, y: f32} + +LPGLYPHMETRICSFLOAT :: ^GLYPHMETRICSFLOAT +GLYPHMETRICSFLOAT :: struct { + gmfBlackBoxX: f32, + gmfBlackBoxY: f32, + gmfptGlyphOrigin: POINTFLOAT, + gmfCellIncX: f32, + gmfCellIncY: f32, +} + +CreateContextAttribsARBType :: #type proc "c" (hdc: HDC, hShareContext: rawptr, attribList: [^]c.int) -> HGLRC +ChoosePixelFormatARBType :: #type proc "c" (hdc: HDC, attribIList: [^]c.int, attribFList: [^]f32, maxFormats: DWORD, formats: [^]c.int, numFormats: [^]DWORD) -> BOOL +SwapIntervalEXTType :: #type proc "c" (interval: c.int) -> bool +GetExtensionsStringARBType :: #type proc "c" (HDC) -> cstring + +// Procedures + wglCreateContextAttribsARB: CreateContextAttribsARBType + wglChoosePixelFormatARB: ChoosePixelFormatARBType + wglSwapIntervalExt: SwapIntervalEXTType + wglGetExtensionsStringARB: GetExtensionsStringARBType + + +@(default_calling_convention="stdcall") +foreign Opengl32 { + wglCreateContext :: proc(hdc: HDC) -> HGLRC --- + wglMakeCurrent :: proc(hdc: HDC, HGLRC: HGLRC) -> BOOL --- + wglGetProcAddress :: proc(c_str: cstring) -> rawptr --- + wglDeleteContext :: proc(HGLRC: HGLRC) -> BOOL --- + wglCopyContext :: proc(src, dst: HGLRC, mask: UINT) -> BOOL --- + wglCreateLayerContext :: proc(hdc: HDC, layer_plane: c.int) -> HGLRC --- + wglDescribeLayerPlane :: proc(hdc: HDC, pixel_format, layer_plane: c.int, bytes: UINT, pd: LPLAYERPLANEDESCRIPTOR) -> BOOL --- + wglGetCurrentContext :: proc() -> HGLRC --- + wglGetCurrentDC :: proc() -> HDC --- + wglGetLayerPaletteEntries :: proc(hdc: HDC, layer_plane, start, entries: c.int, cr: ^COLORREF) -> c.int --- + wglRealizeLayerPalette :: proc(hdc: HDC, layer_plane: c.int, realize: BOOL) -> BOOL --- + wglSetLayerPaletteEntries :: proc(hdc: HDC, layer_plane, start, entries: c.int, cr: ^COLORREF) -> c.int --- + wglShareLists :: proc(HGLRC1, HGLRC2: HGLRC) -> BOOL --- + wglSwapLayerBuffers :: proc(hdc: HDC, planes: DWORD) -> BOOL --- + wglUseFontBitmaps :: proc(hdc: HDC, first, count, list_base: DWORD) -> BOOL --- + wglUseFontOutlines :: proc(hdc: HDC, first, count, list_base: DWORD, deviation, extrusion: f32, format: c.int, gmf: LPGLYPHMETRICSFLOAT) -> BOOL --- +}