├── src
├── linux
│ ├── init.zig
│ ├── context.zig
│ ├── event.zig
│ ├── platform.zig
│ └── window.zig
├── macOS
│ ├── init.zig
│ ├── context.zig
│ ├── event.zig
│ ├── platform.zig
│ └── window.zig
├── demo.frag
├── demo.vert
├── windows
│ ├── gdi32_bs.zig
│ ├── kernel32_bs.zig
│ ├── opengl32_bs.zig
│ ├── platform.zig
│ ├── event.zig
│ ├── user32_bs.zig
│ ├── context.zig
│ ├── init.zig
│ ├── window.zig
│ └── w32.zig
├── event.zig
├── context.zig
├── key.zig
├── main.zig
├── zwl.zig
└── window.zig
├── .gitignore
├── LICENSE
└── README.md
/src/linux/init.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/macOS/init.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/linux/context.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/linux/event.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/linux/platform.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/linux/window.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/macOS/context.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/macOS/event.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/macOS/platform.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/src/macOS/window.zig:
--------------------------------------------------------------------------------
1 | comptime {
2 | @compileError("Platform WIP");
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/.vscode/
2 | **/.zig-cache/
3 | **/zig-cache/
4 | **/zig-out/
5 | **/*.h
6 | **/*.c
--------------------------------------------------------------------------------
/src/demo.frag:
--------------------------------------------------------------------------------
1 | #version 460 core
2 |
3 | out vec4 FragColor;
4 |
5 | in vec3 color;
6 |
7 | void main() {
8 | FragColor = vec4(color, 1);
9 | }
10 |
--------------------------------------------------------------------------------
/src/demo.vert:
--------------------------------------------------------------------------------
1 | #version 460 core
2 |
3 | layout(location = 0) in vec2 aPosition;
4 | layout(location = 1) in vec3 aColor;
5 |
6 | out vec3 color;
7 |
8 | void main() {
9 | gl_Position = vec4(aPosition, 0, 1);
10 | color = aColor;
11 | }
12 |
--------------------------------------------------------------------------------
/src/windows/gdi32_bs.zig:
--------------------------------------------------------------------------------
1 | //! Opengl32 bootstrap for foreign compilation
2 |
3 | pub export fn SetPixelFormat() noreturn {
4 | @panic("Unexpected");
5 | }
6 | pub export fn ChoosePixelFormat() noreturn {
7 | @panic("Unexpected");
8 | }
9 | pub export fn SwapBuffers() noreturn {
10 | @panic("Unexpected");
11 | }
12 |
--------------------------------------------------------------------------------
/src/windows/kernel32_bs.zig:
--------------------------------------------------------------------------------
1 | //! Kernel32 bootstrap for foreign compilation
2 |
3 | pub export fn GetModuleHandleW() noreturn {
4 | @panic("Unexpected");
5 | }
6 | pub export fn GetLastError() noreturn {
7 | @panic("Unexpected");
8 | }
9 | pub export fn SetConsoleOutputCP() noreturn {
10 | @panic("Unexpected");
11 | }
--------------------------------------------------------------------------------
/src/windows/opengl32_bs.zig:
--------------------------------------------------------------------------------
1 | //! Opengl32 bootstrap for foreign compilation
2 |
3 | pub export fn wglCreateContext() noreturn {
4 | @panic("Unexpected");
5 | }
6 | pub export fn wglDeleteContext() noreturn {
7 | @panic("Unexpected");
8 | }
9 | pub export fn wglMakeCurrent() noreturn {
10 | @panic("Unexpected");
11 | }
12 | pub export fn wglGetProcAddress() noreturn {
13 | @panic("Unexpected");
14 | }
15 | pub export fn wglShareLists() noreturn {
16 | @panic("Unexpected");
17 | }
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Darkfllame
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zig Windowing Library
2 | ZWL (Zig Windowing Library, /zwil/) is a cross-platform zig windowing library with loop-based event polling (like SDL) and aimed to be lightweight thanks to zig's conditional compilation/lazy evaluation.
3 |
4 | ## Current state: 
5 |
6 | Win32 
7 |
8 | - [x] Window
9 | - [x] Event
10 | - [x] OpenGL Context
11 |
12 |
13 | Linux 
14 |
15 | - X11 
16 | - [ ] Window
17 | - [ ] Event
18 | - [ ] OpenGL Context
19 | - Wayland 
20 | - [ ] Window
21 | - [ ] Event
22 | - [ ] OpenGL Context
23 |
24 |
25 | MacOS 
26 |
27 | - [ ] Window
28 | - [ ] Event
29 | - [ ] OpenGL Context
30 |
31 |
32 | ###
33 | ZWL is very WIP, so expect bugs, inconsistencies and lack of support on certain platforms. If you wish you can help me by [contributing](#contributing) to this project via pull requests or filing issues.
34 |
35 | # Contributing
36 | Feel free to contribute to the library by making PRs or by filing issues. My machine is a windows one, so I'll prioritize my work (and might only work) on the Win32 implementation.
--------------------------------------------------------------------------------
/src/windows/platform.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const Zwl = @import("../Zwl.zig");
3 | const init = @import("init.zig");
4 | const window = @import("window.zig");
5 | const event = @import("event.zig");
6 | const context = @import("context.zig");
7 | pub const W32 = @import("w32.zig");
8 |
9 | const Platform = Zwl.Platform;
10 |
11 | pub const NativeData = init.NativeData;
12 | pub const Window = window.NativeWindow;
13 | pub const GLContext = context.GLContext;
14 | pub const platform = Zwl.Platform{
15 | .init = &init.init,
16 | .deinit = &init.deinit,
17 | .keyName = &init.keyName,
18 | .window = .{
19 | .createMessageBox = &window.NativeWindow.createMessageBox,
20 | .init = &window.NativeWindow.init,
21 | .deinit = &window.NativeWindow.deinit,
22 | .setPosition = &window.NativeWindow.setPosition,
23 | .setSize = &window.NativeWindow.setSize,
24 | .setSizeLimits = &window.NativeWindow.setSizeLimits,
25 | .getFramebufferSize = &window.NativeWindow.getFramebufferSize,
26 | .setVisible = &window.NativeWindow.setVisible,
27 | .setTitle = &window.NativeWindow.setTitle,
28 | .isFocused = &window.NativeWindow.isFocused,
29 | .getMousePos = &window.NativeWindow.getMousePos,
30 | .setMousePos = &window.NativeWindow.setMousePos,
31 | .setMouseVisible = &window.NativeWindow.setMouseVisible,
32 | .setFocus = &window.NativeWindow.setFocus,
33 | .setMouseConfined = &window.NativeWindow.setMouseConfined,
34 | },
35 | .event = .{
36 | .pollEvent = &event.pollEvent,
37 | },
38 | .glContext = .{
39 | .init = &context.GLContext.init,
40 | .deinit = &context.GLContext.deinit,
41 | .makeCurrent = &context.GLContext.makeCurrent,
42 | .swapBuffers = &context.GLContext.swapBuffers,
43 | .swapInterval = &context.GLContext.swapInterval,
44 | },
45 | };
--------------------------------------------------------------------------------
/src/windows/event.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const Zwl = @import("../Zwl.zig");
3 | const W32 = @import("w32.zig");
4 | const window = @import("window.zig");
5 | const event = @import("../event.zig");
6 |
7 | const Window = Zwl.Window;
8 | const Error = Zwl.Error;
9 | const Event = Zwl.Event;
10 | const Key = Zwl.Key;
11 |
12 | pub var pollingError: ?Error = null;
13 |
14 | pub fn pollEvent(lib: *Zwl, opt_window: ?*Window) Error!void {
15 | pollingError = null;
16 |
17 | var msg: W32.MSG = undefined;
18 |
19 | if (W32.PeekMessageW(
20 | &msg,
21 | if (opt_window) |wnd| wnd.native.handle else null,
22 | 0,
23 | 0,
24 | W32.PM_REMOVE,
25 | ) != 0) {
26 | switch (msg.message) {
27 | W32.WM_QUIT => try queueEvent(lib, .{ .quit = msg.wParam }),
28 | else => {
29 | _ = W32.TranslateMessage(&msg);
30 | _ = W32.DispatchMessageW(&msg);
31 | },
32 | }
33 | }
34 |
35 | if (pollingError) |pErr| return pErr;
36 |
37 | if (W32.GetActiveWindow()) |handle| {
38 | if (@as(?*Window, @ptrCast(@alignCast(W32.GetPropW(handle, window.WND_PTR_PROP_NAME.ptr))))) |wnd| {
39 | const keys = [_]struct { u8, Key }{
40 | .{ 0xA0, .left_shift },
41 | .{ 0xA1, .right_shift },
42 | .{ 0x5B, .left_super },
43 | .{ 0x5C, .right_super },
44 | };
45 |
46 | for (keys) |keypair| {
47 | const vk = keypair[0];
48 | const key = keypair[1];
49 |
50 | if (W32.GetKeyState(vk) & 0x8000 != 0) {
51 | continue;
52 | }
53 | if (!wnd.keys[@intFromEnum(key)]) {
54 | continue;
55 | }
56 |
57 | try queueEvent(lib, .{ .key = .{
58 | .window = wnd,
59 | .key = key,
60 | .action = .release,
61 | .mods = window.getKeyMods(),
62 | } });
63 | }
64 | }
65 | }
66 | }
67 |
68 | pub const queueEvent = event.queueEvent;
69 |
--------------------------------------------------------------------------------
/src/event.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 | const config = @import("config");
4 | const Zwl = @import("Zwl.zig");
5 | pub const Key = @import("key.zig").Key;
6 |
7 | const Error = Zwl.Error;
8 | const Window = Zwl.Window;
9 |
10 | pub const Event = union(enum) {
11 | quit: u64,
12 | windowClosed: *Window,
13 | windowFocused: struct {
14 | window: *Window,
15 | gained: bool,
16 | },
17 | windowResized: struct {
18 | window: *Window,
19 | width: u16,
20 | height: u16,
21 | },
22 | windowMoved: struct {
23 | window: *Window,
24 | x: u16,
25 | y: u16,
26 | },
27 | mouseMoved: struct {
28 | window: *Window,
29 | x: u16,
30 | y: u16,
31 | dx: i16,
32 | dy: i16,
33 | },
34 | mouseButton: struct {
35 | window: *Window,
36 | clicked: bool,
37 | /// | value | button |
38 | /// |-|-|
39 | /// |1|left|
40 | /// |2|middle|
41 | /// |3|right|
42 | /// |4|4th button|
43 | /// |5|5th button|
44 | /// and so on...
45 | button: u8,
46 | mods: EventMods,
47 | },
48 | mouseWheel: struct {
49 | window: *Window,
50 | x: f32,
51 | y: f32,
52 | mods: EventMods,
53 | },
54 | key: struct {
55 | window: *Window,
56 | key: Key,
57 | action: Key.Action,
58 | mods: Key.Mods,
59 | },
60 |
61 | pub const EventMods = packed struct {
62 | control: bool,
63 | shift: bool,
64 | };
65 | };
66 |
67 | pub fn pollEvent(lib: *Zwl, opt_window: ?*Window) Error!?Event {
68 | return popQueue(lib) orelse {
69 | try lib.platform.event.pollEvent(lib, opt_window);
70 | return popQueue(lib);
71 | };
72 | }
73 |
74 | fn popQueue(lib: *Zwl) ?Event {
75 | if (lib.eventQueueSize > 0) {
76 | const retItem = lib.eventQueue[0];
77 | lib.eventQueueSize -= 1;
78 | if (lib.eventQueueSize > 1) {
79 | for (lib.eventQueue[1..lib.eventQueueSize], 0..) |item, i| {
80 | lib.eventQueue[i] = item;
81 | }
82 | }
83 | return retItem;
84 | }
85 | return null;
86 | }
87 |
88 | pub fn queueEvent(lib: *Zwl, event: Event) Error!void {
89 | const newSize = lib.eventQueueSize + 1;
90 | if (newSize > lib.eventQueue.len) {
91 | return Error.QueueFull;
92 | }
93 | lib.eventQueue[newSize - 1] = event;
94 | lib.eventQueueSize = newSize;
95 | }
96 |
--------------------------------------------------------------------------------
/src/context.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 | const Zwl = @import("Zwl.zig");
4 |
5 | const Error = Zwl.Error;
6 | const Window = Zwl.Window;
7 |
8 | pub const GLContext = struct {
9 | owner: *Window,
10 | config: Config,
11 | native: Zwl.platform.GLContext,
12 |
13 | pub const VersionAPI = enum(u2) {
14 | opengl,
15 | opengl_es,
16 | };
17 | pub const OpenGLProfile = enum(u2) {
18 | any,
19 | core,
20 | compat,
21 | };
22 | pub const Version = struct {
23 | api: VersionAPI = .opengl,
24 | major: u8 = 0,
25 | minor: u8 = 0,
26 | };
27 | pub const Config = struct {
28 | version: Version = .{},
29 | debug: bool = builtin.mode == .Debug,
30 | forward: bool = false,
31 | profile: OpenGLProfile = .any,
32 | share: ?*GLContext = null,
33 | pixelFormat: PixelFormat = .{},
34 | };
35 | pub const PixelFormat = packed struct(u56) {
36 | /// 0 means default
37 | redBits: u8 = 0,
38 | /// 0 means default
39 | greenBits: u8 = 0,
40 | /// 0 means default
41 | blueBits: u8 = 0,
42 | /// 0 means default
43 | alphaBits: u8 = 0,
44 | /// 0 means default
45 | depthBits: u8 = 0,
46 | /// 0 means default
47 | stencilBits: u8 = 0,
48 | /// 0 means default
49 | samples: u8 = 0,
50 | };
51 |
52 | pub fn create(window: *Window, config: Config) Error!*GLContext {
53 | const lib = window.owner;
54 | const allocator = lib.allocator;
55 | const self = allocator.create(GLContext) catch |e| {
56 | return lib.setError("Cannot create GLContext", .{}, e);
57 | };
58 | errdefer allocator.destroy(self);
59 | try self.init(window, config);
60 | return self;
61 | }
62 | pub fn init(self: *GLContext, window: *Window, config: Config) Error!void{
63 | const lib = window.owner;
64 | self.owner = window;
65 | self.config = config;
66 | try lib.platform.glContext.init(&self.native, lib, window, config);
67 | }
68 | pub fn destroy(self: *GLContext) void {
69 | const lib = self.owner.owner;
70 | self.deinit();
71 | lib.allocator.destroy(self);
72 | }
73 | pub fn deinit(self: *GLContext) void {
74 | const lib = self.owner.owner;
75 | lib.platform.glContext.deinit(&self.native);
76 | }
77 |
78 | pub fn makeCurrent(lib: *Zwl, opt_ctx: ?*GLContext) Error!void {
79 | if (opt_ctx) |ctx| {
80 | if (ctx.owner.owner != lib) {
81 | @panic("Bad library passed to GLContext.makeCurrent");
82 | }
83 | }
84 | return lib.platform.glContext.makeCurrent(lib, opt_ctx);
85 | }
86 | pub fn swapBuffers(ctx: *GLContext) Error!void {
87 | return ctx.owner.owner.platform.glContext.swapBuffers(ctx);
88 | }
89 | pub fn swapInterval(lib: *Zwl, interval: i32) Error!void {
90 | return lib.platform.glContext.swapInterval(lib, interval);
91 | }
92 | };
93 |
--------------------------------------------------------------------------------
/src/key.zig:
--------------------------------------------------------------------------------
1 | pub const Key = enum(u16) {
2 | pub const Action = enum(u2) {
3 | release = 0,
4 | press,
5 | repeat,
6 | };
7 |
8 | pub const Mods = packed struct {
9 | shift: bool = false,
10 | control: bool = false,
11 | alt: bool = false,
12 | super: bool = false,
13 | capsLock: bool = false,
14 | numLock: bool = false,
15 | };
16 |
17 | unkown = 0xFFFF,
18 | space = 32,
19 | apostrophe = 39,
20 | comma = 44,
21 | minus = 45,
22 | period = 46,
23 | slash = 47,
24 | @"0" = 48,
25 | @"1" = 49,
26 | @"2" = 50,
27 | @"3" = 51,
28 | @"4" = 52,
29 | @"5" = 53,
30 | @"6" = 54,
31 | @"7" = 55,
32 | @"8" = 56,
33 | @"9" = 57,
34 | semicolon = 59,
35 | equal = 61,
36 | a = 65,
37 | b = 66,
38 | c = 67,
39 | d = 68,
40 | e = 69,
41 | f = 70,
42 | g = 71,
43 | h = 72,
44 | i = 73,
45 | j = 74,
46 | k = 75,
47 | l = 76,
48 | m = 77,
49 | n = 78,
50 | o = 79,
51 | p = 80,
52 | q = 81,
53 | r = 82,
54 | s = 83,
55 | t = 84,
56 | u = 85,
57 | v = 86,
58 | w = 87,
59 | x = 88,
60 | y = 89,
61 | z = 90,
62 | left_bracket = 91,
63 | backslash = 92,
64 | right_bracket = 93,
65 | grave_accent = 96,
66 | world_1 = 161,
67 | world_2 = 162,
68 | escape = 256,
69 | enter = 257,
70 | tab = 258,
71 | backspace = 259,
72 | insert = 260,
73 | delete = 261,
74 | right = 262,
75 | left = 263,
76 | down = 264,
77 | up = 265,
78 | page_up = 266,
79 | page_down = 267,
80 | home = 268,
81 | end = 269,
82 | caps_lock = 280,
83 | scroll_lock = 281,
84 | num_lock = 282,
85 | print_screen = 283,
86 | pause = 284,
87 | f1 = 290,
88 | f2 = 291,
89 | f3 = 292,
90 | f4 = 293,
91 | f5 = 294,
92 | f6 = 295,
93 | f7 = 296,
94 | f8 = 297,
95 | f9 = 298,
96 | f10 = 299,
97 | f11 = 300,
98 | f12 = 301,
99 | f13 = 302,
100 | f14 = 303,
101 | f15 = 304,
102 | f16 = 305,
103 | f17 = 306,
104 | f18 = 307,
105 | f19 = 308,
106 | f20 = 309,
107 | f21 = 310,
108 | f22 = 311,
109 | f23 = 312,
110 | f24 = 313,
111 | f25 = 314,
112 | kp_0 = 320,
113 | kp_1 = 321,
114 | kp_2 = 322,
115 | kp_3 = 323,
116 | kp_4 = 324,
117 | kp_5 = 325,
118 | kp_6 = 326,
119 | kp_7 = 327,
120 | kp_8 = 328,
121 | kp_9 = 329,
122 | kp_decimal = 330,
123 | kp_divide = 331,
124 | kp_multiply = 332,
125 | kp_subtract = 333,
126 | kp_add = 334,
127 | kp_enter = 335,
128 | kp_equal = 336,
129 | left_shift = 340,
130 | left_control = 341,
131 | left_alt = 342,
132 | left_super = 343,
133 | right_shift = 344,
134 | right_control = 345,
135 | right_alt = 346,
136 | right_super = 347,
137 | menu = 348,
138 | /// Isn't used except to get the
139 | /// `Window.keys` size
140 | last = 349,
141 | };
142 |
--------------------------------------------------------------------------------
/src/windows/user32_bs.zig:
--------------------------------------------------------------------------------
1 | //! User32 bootstrap for foreign compilation
2 |
3 | pub export fn GetSystemMetrics() noreturn {
4 | @panic("Unexpected");
5 | }
6 | pub export fn CreateWindowExW() noreturn {
7 | @panic("Unexpected");
8 | }
9 | pub export fn DestroyWindow() noreturn {
10 | @panic("Unexpected");
11 | }
12 | pub export fn DefWindowProcW() noreturn {
13 | @panic("Unexpected");
14 | }
15 | pub export fn RegisterClassExW() noreturn {
16 | @panic("Unexpected");
17 | }
18 | pub export fn UnregisterClassW() noreturn {
19 | @panic("Unexpected");
20 | }
21 | pub export fn LoadCursorW() noreturn {
22 | @panic("Unexpected");
23 | }
24 | pub export fn GetPropW() noreturn {
25 | @panic("Unexpected");
26 | }
27 | pub export fn SetPropW() noreturn {
28 | @panic("Unexpected");
29 | }
30 | pub export fn GetActiveWindow() noreturn {
31 | @panic("Unexpected");
32 | }
33 | pub export fn SetActiveWindow() noreturn {
34 | @panic("Unexpected");
35 | }
36 | pub export fn SetFocus() noreturn {
37 | @panic("Unexpected");
38 | }
39 | pub export fn PeekMessageW() noreturn {
40 | @panic("Unexpected");
41 | }
42 | pub export fn TranslateMessage() noreturn {
43 | @panic("Unexpected");
44 | }
45 | pub export fn DispatchMessageW() noreturn {
46 | @panic("Unexpected");
47 | }
48 | pub export fn ClientToScreen() noreturn {
49 | @panic("Unexpected");
50 | }
51 | pub export fn AdjustWindowRectEx() noreturn {
52 | @panic("Unexpected");
53 | }
54 | pub export fn GetClientRect() noreturn {
55 | @panic("Unexpected");
56 | }
57 | pub export fn SetWindowPos() noreturn {
58 | @panic("Unexpected");
59 | }
60 | pub export fn GetDC() noreturn {
61 | @panic("Unexpected");
62 | }
63 | pub export fn ShowWindow() noreturn {
64 | @panic("Unexpected");
65 | }
66 | pub export fn SetWindowTextW() noreturn {
67 | @panic("Unexpected");
68 | }
69 | pub export fn GetWindowTextLengthW() noreturn {
70 | @panic("Unexpected");
71 | }
72 | pub export fn GetWindowTextW() noreturn {
73 | @panic("Unexpected");
74 | }
75 | pub export fn GetWindowRect() noreturn {
76 | @panic("Unexpected");
77 | }
78 | pub export fn MoveWindow() noreturn {
79 | @panic("Unexpected");
80 | }
81 | pub export fn GetCursorPos() noreturn {
82 | @panic("Unexpected");
83 | }
84 | pub export fn SetCursorPos() noreturn {
85 | @panic("Unexpected");
86 | }
87 | pub export fn ScreenToClient() noreturn {
88 | @panic("Unexpected");
89 | }
90 | pub export fn SetCursor() noreturn {
91 | @panic("Unexpected");
92 | }
93 | pub export fn ClipCursor() noreturn {
94 | @panic("Unexpected");
95 | }
96 | pub export fn WindowFromPoint() noreturn {
97 | @panic("Unexpected");
98 | }
99 | pub export fn PtInRect() noreturn {
100 | @panic("Unexpected");
101 | }
102 | pub export fn ShowCursor() noreturn {
103 | @panic("Unexpected");
104 | }
105 | pub export fn GetKeyState() noreturn {
106 | @panic("Unexpected");
107 | }
108 | pub export fn MapVirtualKeyW() noreturn {
109 | @panic("Unexpected");
110 | }
111 | pub export fn GetMessageTime() noreturn {
112 | @panic("Unexpected");
113 | }
114 | pub export fn MessageBoxW() noreturn {
115 | @panic("Unexpected");
116 | }
117 | pub export fn ToUniform() noreturn {
118 | @panic("Unexpected");
119 | }
120 | pub export fn SendMessage() noreturn {
121 | @panic("Unexpected");
122 | }
123 |
--------------------------------------------------------------------------------
/src/main.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 | const Zwl = @import("zwl");
4 | const GL = @import("zgll").GL;
5 |
6 | const VERTEX_SHADER_SOURCE: []const u8 = @embedFile("demo.vert");
7 | const FRAGMENT_SHADER_SOURCE: []const u8 = @embedFile("demo.frag");
8 | const TRIANGLE_VERTICES = [_]f32{
9 | -0.5, -0.5, 1, 0, 0,
10 | 0.5, -0.5, 0, 1, 0,
11 | 0, 0.5, 0, 0, 1,
12 | };
13 |
14 | pub fn main() !void {
15 | if (builtin.os.tag == .windows) {
16 | // manually set console output mode for windows, because zig doesn't
17 | const W32 = Zwl.platform.W32;
18 | _ = W32.SetConsoleOutputCP(W32.CP_UTF8);
19 | } else if (builtin.os.tag == .linux) {
20 | return linuxMain();
21 | }
22 |
23 | const DEBUG = builtin.mode == .Debug;
24 | var gpa = if (DEBUG)
25 | std.heap.GeneralPurposeAllocator(.{}){}
26 | else {};
27 | defer _ = if (DEBUG) gpa.deinit();
28 | const allocator = if (DEBUG) gpa.allocator() else std.heap.page_allocator;
29 |
30 | const zwl = try allocator.create(Zwl);
31 | defer allocator.destroy(zwl);
32 |
33 | errdefer |e| {
34 | std.debug.print("[FATAL | {s}] {s}\n", .{ @errorName(e), zwl.getError() });
35 | }
36 |
37 | try zwl.init(allocator, .{});
38 | defer zwl.deinit();
39 |
40 | const window = try zwl.createWindow(.{
41 | .title = "ZWL demo",
42 | .width = 800,
43 | .height = 600,
44 | });
45 | defer window.destroy();
46 |
47 | const ctx = try window.createGLContext(Zwl.GLContext.Config{
48 | .pixelFormat = .{ .samples = 8 },
49 | .version = .{
50 | .major = 3,
51 | .minor = 2,
52 | },
53 | });
54 | defer ctx.destroy();
55 | try zwl.makeContextCurrent(ctx);
56 |
57 | const gl = try allocator.create(GL);
58 | defer allocator.destroy(gl);
59 | try gl.init(null);
60 |
61 | std.debug.print("Using OpenGL {s}\n", .{gl.getString(GL.VERSION).?});
62 |
63 | var VAO: u32 = 0;
64 | gl.genVertexArrays(1, @ptrCast(&VAO));
65 | defer gl.deleteVertexArrays(1, @ptrCast(&VAO));
66 |
67 | var VBO: u32 = 0;
68 | gl.genBuffers(1, @ptrCast(&VBO));
69 | defer gl.deleteBuffers(1, @ptrCast(&VBO));
70 |
71 | gl.bindVertexArray(VAO);
72 |
73 | gl.bindBuffer(GL.ARRAY_BUFFER, VBO);
74 |
75 | gl.bufferData(GL.ARRAY_BUFFER, @sizeOf(@TypeOf(TRIANGLE_VERTICES)), &TRIANGLE_VERTICES, GL.STATIC_DRAW);
76 |
77 | gl.vertexAttribPointer(0, 2, GL.FLOAT, false, @sizeOf(f32) * 5, 0);
78 | gl.enableVertexArrayAttrib(VAO, 0);
79 |
80 | gl.vertexAttribPointer(1, 3, GL.FLOAT, false, @sizeOf(f32) * 5, @sizeOf(f32) * 2);
81 | gl.enableVertexArrayAttrib(VAO, 1);
82 |
83 | gl.bindBuffer(GL.ARRAY_BUFFER, 0);
84 |
85 | gl.bindVertexArray(0);
86 |
87 | const shaderProgram = gl.createProgram();
88 | defer gl.deleteProgram(shaderProgram);
89 | {
90 | const vertexShader = gl.createShader(GL.VERTEX_SHADER);
91 | defer gl.deleteShader(vertexShader);
92 | gl.shaderSource(vertexShader, 1, @ptrCast(&VERTEX_SHADER_SOURCE.ptr), null);
93 | gl.compileShader(vertexShader);
94 |
95 | const fragmentShader = gl.createShader(GL.FRAGMENT_SHADER);
96 | defer gl.deleteShader(fragmentShader);
97 | gl.shaderSource(fragmentShader, 1, @ptrCast(&FRAGMENT_SHADER_SOURCE.ptr), null);
98 | gl.compileShader(fragmentShader);
99 |
100 | gl.attachShader(shaderProgram, vertexShader);
101 | defer gl.detachShader(shaderProgram, vertexShader);
102 | gl.attachShader(shaderProgram, fragmentShader);
103 | defer gl.detachShader(shaderProgram, fragmentShader);
104 |
105 | gl.linkProgram(shaderProgram);
106 | }
107 |
108 | gl.viewport(0, 0, 800, 600);
109 | gl.enable(GL.MULTISAMPLE);
110 | gameloop: while (true) {
111 | while (try zwl.pollEvent(null)) |event| {
112 | switch (event) {
113 | .quit, .windowClosed => break :gameloop,
114 | .key => |input| if (input.action == .press) {
115 | std.debug.print("key pressed: {s}\n", .{zwl.keyName(input.key) orelse @tagName(input.key)});
116 | },
117 | else => {},
118 | }
119 | }
120 |
121 | gl.clearColor(0, 0, 0, 1);
122 | gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
123 |
124 | gl.useProgram(shaderProgram);
125 |
126 | gl.bindVertexArray(VAO);
127 | gl.drawArrays(GL.TRIANGLES, 0, 3);
128 | gl.bindVertexArray(0);
129 |
130 | gl.useProgram(0);
131 |
132 | try ctx.swapBuffers();
133 | }
134 | }
135 |
136 | fn linuxMain() !void {
137 | std.debug.print("Hello, World!\n", .{});
138 | // const DEBUG = builtin.mode == .Debug;
139 | // var gpa = if (DEBUG)
140 | // std.heap.GeneralPurposeAllocator(.{}){}
141 | // else {};
142 | // defer _ = if (DEBUG) gpa.deinit();
143 | // const allocator = if (DEBUG) gpa.allocator() else std.heap.page_allocator;
144 |
145 | // const zwl = try allocator.create(ZWL.Zwl);
146 | // defer allocator.destroy(zwl);
147 |
148 | // errdefer |e| {
149 | // std.debug.print("[FATAL | {s}] {s}\n", .{ @errorName(e), zwl.getError() });
150 | // }
151 |
152 | // try zwl.init(allocator, .{});
153 | // defer zwl.deinit();
154 | }
155 |
--------------------------------------------------------------------------------
/src/zwl.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 | const config = @import("config");
4 | const window = @import("window.zig");
5 | const event = @import("event.zig");
6 | const context = @import("context.zig");
7 |
8 | const Allocator = std.mem.Allocator;
9 | const Zwl = @This();
10 |
11 | pub const platform = switch (builtin.os.tag) {
12 | .windows => @import("windows/platform.zig"),
13 | .linux => @import("linux/platform.zig"),
14 | .macos => @import("macos/platform.zig"),
15 | else => @compileError("Unsupported target"),
16 | };
17 |
18 | pub const Window = window.Window;
19 | pub const Event = event.Event;
20 | pub const Key = event.Key;
21 | pub const GLContext = context.GLContext;
22 |
23 | pub const Error = error{
24 | Cocoa,
25 | InvalidUtf8,
26 | OutOfMemory,
27 | QueueFull,
28 | X11,
29 | Wayland,
30 | Win32,
31 | };
32 |
33 | pub const Config = struct {};
34 |
35 | comptime platform: Platform = if (@hasDecl(platform, "platform") and @TypeOf(platform.platform) == Platform)
36 | platform.platform
37 | else
38 | @compileError("Expected platform.setPlatform to be 'fn (*Platform) Error!void'"),
39 |
40 | allocator: Allocator,
41 | errorBuffer: [config.ERROR_BUFFER_SIZE]u8,
42 | errFormatBuffer: [config.ERROR_BUFFER_SIZE]u8,
43 | currentError: ?[]u8,
44 | eventQueueSize: usize,
45 | eventQueue: [config.EVENT_QUEUE_SIZE]Event,
46 | native: platform.NativeData,
47 |
48 | pub fn init(self: *Zwl, allocator: Allocator, _config: Config) Error!void {
49 | @memset(std.mem.asBytes(self), 0);
50 | self.allocator = allocator;
51 | try self.platform.init(self, _config);
52 | }
53 | pub fn deinit(self: *Zwl) void {
54 | self.platform.deinit(self);
55 | }
56 |
57 | pub fn clearError(self: *Zwl) void {
58 | self.currentError = null;
59 | }
60 | pub fn getError(self: *const Zwl) []const u8 {
61 | return self.currentError orelse config.DEFAULT_ERROR_MESSAGE;
62 | }
63 | pub fn setError(self: *Zwl, comptime fmt: []const u8, args: anytype, err: anytype) @TypeOf(err) {
64 | if (@typeInfo(@TypeOf(err)) != .ErrorSet) {
65 | @compileError("'err' must be an error");
66 | }
67 |
68 | self.clearError();
69 |
70 | const formatted = std.fmt.bufPrint(&self.errFormatBuffer, fmt, args) catch blk: {
71 | const TRUNC_MESSAGE = " (truncated)";
72 | @memcpy(
73 | self.errFormatBuffer[self.errFormatBuffer.len - TRUNC_MESSAGE.len ..],
74 | TRUNC_MESSAGE,
75 | );
76 | break :blk &self.errFormatBuffer;
77 | };
78 |
79 | self.currentError = self.errorBuffer[0..formatted.len];
80 |
81 | @memcpy(self.currentError.?, formatted);
82 |
83 | return err;
84 | }
85 |
86 | pub fn keyName(self: *const Zwl, key: Key) ?[:0]const u8 {
87 | return self.platform.keyName(self, key);
88 | }
89 |
90 | pub const createWindow = Window.create;
91 | pub const createMessageBox = Window.createMessageBox;
92 |
93 | pub const pollEvent = event.pollEvent;
94 |
95 | pub const makeContextCurrent = GLContext.makeCurrent;
96 | pub const swapInterval = GLContext.swapInterval;
97 |
98 | pub const Platform = struct {
99 | init: *const fn (*Zwl, Config) Error!void,
100 | deinit: *const fn (*Zwl) void,
101 | keyName: *const fn (*const Zwl, Key) [:0]const u8,
102 | window: struct {
103 | createMessageBox: *const fn (*Zwl, Window.MBConfig) Error!Window.MBButton,
104 | init: *const fn (*platform.Window, *Zwl, Window.Config) Error!void,
105 | deinit: *const fn (*platform.Window) void,
106 | setPosition: *const fn (*Window, u32, u32) void,
107 | setSize: *const fn (*Window, u32, u32) void,
108 | setSizeLimits: *const fn (*Window, ?u32, ?u32, ?u32, ?u32) void,
109 | getFramebufferSize: *const fn (*Window, ?*u32, ?*u32) void,
110 | setVisible: *const fn (*Window, bool) void,
111 | setTitle: *const fn (*Window, []const u8) Error!void,
112 | isFocused: *const fn (*Window) bool,
113 | getMousePos: *const fn (*Window, ?*u32, ?*u32) void,
114 | setMousePos: *const fn (*Window, u32, u32) void,
115 | setMouseVisible: *const fn (*Window, bool) void,
116 | setFocus: *const fn (*Window) void,
117 | setMouseConfined: *const fn (*Window, bool) void,
118 | },
119 | event: struct {
120 | pollEvent: *const fn (*Zwl, ?*Window) Error!void,
121 | },
122 | glContext: struct {
123 | init: *const fn (*platform.GLContext, *Zwl, *Window, GLContext.Config) Error!void,
124 | deinit: *const fn (*platform.GLContext) void,
125 | makeCurrent: *const fn (*Zwl, ?*GLContext) Error!void,
126 | swapBuffers: *const fn (*GLContext) Error!void,
127 | swapInterval: *const fn (*Zwl, i32) Error!void,
128 | },
129 | };
130 |
131 | pub fn MBpanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn {
132 | @setCold(true);
133 | const S = struct {
134 | var inPanic: bool = false;
135 | };
136 | if (S.inPanic) {
137 | std.builtin.default_panic("Panic in panic, aborting", error_return_trace, null);
138 | }
139 | S.inPanic = true;
140 | const first_ret_addr = ret_addr orelse @returnAddress();
141 |
142 | var text: [4096]u8 = undefined;
143 | var len: usize = 0;
144 | var fbs = std.io.fixedBufferStream(&text);
145 | fbs.writer().print("{s}\n", .{msg}) catch {};
146 | if (!builtin.strip_debug_info) {
147 | if (std.debug.getSelfDebugInfo()) |dbi| {
148 | std.debug.writeCurrentStackTrace(
149 | fbs.writer(),
150 | dbi,
151 | .no_color,
152 | first_ret_addr,
153 | ) catch {};
154 | } else |_| {}
155 | }
156 | if (error_return_trace) |ert| {
157 | ert.format("", .{}, fbs.writer()) catch {};
158 | }
159 | len = fbs.pos;
160 | const mbText = text[0..len];
161 |
162 | var title: [4096]u8 = undefined;
163 | fbs = std.io.fixedBufferStream(&title);
164 | len = 0;
165 | if (@import("builtin").single_threaded) {
166 | fbs.writer().print("panic", .{}) catch {};
167 | } else {
168 | fbs.writer().print("thread {d} panic", .{std.Thread.getCurrentId()}) catch {};
169 | }
170 | len = fbs.pos;
171 |
172 | var zwl: Zwl = undefined;
173 | zwl.init(std.heap.page_allocator, .{}) catch
174 | std.builtin.default_panic(msg, @errorReturnTrace(), null);
175 |
176 | const ret = zwl.createMessageBox(.{
177 | .title = title[0..len],
178 | .text = mbText,
179 | .icon = .@"error",
180 | });
181 | zwl.deinit();
182 | if (ret) |_| {} else |_| {}
183 | std.builtin.default_panic(msg, error_return_trace, first_ret_addr);
184 | }
185 |
186 | comptime {
187 | if (@sizeOf(c_int) != 4) {
188 | @compileError("Bad target platform, c_int MUST be 32 bits");
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/window.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 | const Zwl = @import("Zwl.zig");
4 |
5 | const Allocator = std.mem.Allocator;
6 |
7 | const Key = Zwl.Key;
8 | const Error = Zwl.Error;
9 | const GLContext = Zwl.GLContext;
10 |
11 | const MAX_U32 = std.math.maxInt(u32);
12 |
13 | pub const Window = struct {
14 | owner: *Zwl,
15 | config: Config,
16 | mouse: struct {
17 | lastY: u16 = 0,
18 | lastX: u16 = 0,
19 | } = .{},
20 | lastY: u16 = 0,
21 | lastX: u16 = 0,
22 | keys: [@intFromEnum(Key.last)]bool = std.mem.zeroes([@intFromEnum(Key.last)]bool),
23 | mouseButtons: [5]bool = [_]bool{false} ** 5,
24 | native: Zwl.platform.Window,
25 |
26 | pub const Flags = packed struct {
27 | resizable: bool = false,
28 | hidden: bool = false,
29 | noDecoration: bool = false,
30 | floating: bool = false,
31 | hideMouse: bool = false,
32 | hasFocus: bool = false,
33 | fullscreen: bool = false,
34 | };
35 |
36 | pub const Position = union(enum) {
37 | default,
38 | pos: u32,
39 |
40 | pub inline fn toNumber(self: Position, default: u32) u32 {
41 | return switch (self) {
42 | .default => default,
43 | .pos => |pos| pos,
44 | };
45 | }
46 | };
47 |
48 | pub const SizeLimits = struct {
49 | wmin: ?u32 = null,
50 | wmax: ?u32 = null,
51 | hmin: ?u32 = null,
52 | hmax: ?u32 = null,
53 | };
54 |
55 | pub const Config = struct {
56 | title: []const u8,
57 | width: u32,
58 | height: u32,
59 | x: Position = .default,
60 | y: Position = .default,
61 | sizeLimits: SizeLimits = .{},
62 | flags: Flags = .{},
63 | aspectRatio: ?struct {
64 | numer: u32,
65 | denom: u32,
66 | } = null,
67 | };
68 |
69 | pub const MBMode = enum {
70 | ok,
71 | okCancel,
72 | abortRetryIgnore,
73 | yesNoCancel,
74 | yesNo,
75 | retryCancel,
76 | cancelTryContinue,
77 | };
78 |
79 | pub const MBButton = enum {
80 | ok,
81 | cancel,
82 | abort,
83 | retry,
84 | ignore,
85 | yes,
86 | no,
87 | tryAgain,
88 | @"continue",
89 | };
90 |
91 | pub const MBIcon = enum {
92 | none,
93 | @"error",
94 | question,
95 | warning,
96 | information,
97 | };
98 |
99 | pub const MBConfig = struct {
100 | title: []const u8,
101 | text: []const u8,
102 | parent: ?*Window = null,
103 | mode: MBMode = .ok,
104 | icon: MBIcon = .none,
105 | };
106 |
107 | pub fn create(owner: *Zwl, config: Config) Error!*Window {
108 | const self = owner.allocator.create(Window) catch |e| {
109 | return owner.setError("Cannot allocate window", .{}, e);
110 | };
111 | errdefer owner.allocator.destroy(self);
112 | try self.init(owner, config);
113 | return self;
114 | }
115 | pub fn init(self: *Window, owner: *Zwl, config: Config) Error!void {
116 | std.debug.assert((config.sizeLimits.wmin orelse 0) <
117 | (config.sizeLimits.wmax orelse MAX_U32));
118 | std.debug.assert((config.sizeLimits.hmin orelse 0) <
119 | (config.sizeLimits.hmax orelse MAX_U32));
120 |
121 | self.* = Window{
122 | .owner = owner,
123 | .config = config,
124 | .native = undefined,
125 | };
126 |
127 | self.config.title = owner.allocator.dupe(u8, config.title) catch |e| {
128 | return owner.setError("Cannot copy window title", .{}, e);
129 | };
130 | errdefer owner.allocator.free(self.config.title);
131 |
132 | try owner.platform.window.init(&self.native, owner, config);
133 | errdefer owner.platform.window.deinit(&self.native);
134 | }
135 |
136 | pub fn destroy(self: *Window) void {
137 | self.deinit();
138 | self.owner.allocator.destroy(self);
139 | }
140 | pub fn deinit(self: *Window) void {
141 | self.setMouseConfined(false);
142 | self.owner.allocator.free(self.config.title);
143 | self.owner.platform.window.deinit(&self.native);
144 | }
145 |
146 | pub fn createMessageBox(owner: *Zwl, config: MBConfig) Error!MBButton {
147 | return owner.platform.window.createMessageBox(owner, config);
148 | }
149 |
150 | pub const createGLContext = GLContext.create;
151 |
152 | pub fn getPosition(self: *Window, x: ?*u32, y: ?*u32) void {
153 | return self.owner.platform.window.getPosition(self, x, y);
154 | }
155 | pub fn setPosition(self: *Window, x: u32, y: u32) void {
156 | if (self.lastX == x and
157 | self.lastY == y) return;
158 | self.lastX = x;
159 | self.lastY = y;
160 | return self.owner.platform.window.setPosition(self, x, y);
161 | }
162 | pub fn getSize(self: *Window, w: ?*u32, h: ?*u32) void {
163 | if (w) |wp| wp.* = self.config.width;
164 | if (h) |hp| hp.* = self.config.height;
165 | }
166 | pub fn setSize(self: *Window, w: u32, h: u32) void {
167 | if (self.config.width == w and
168 | self.config.height == h) return;
169 |
170 | const sl = self.config.sizeLimits;
171 | const width = std.math.clamp(
172 | w,
173 | sl.wmin orelse 0,
174 | sl.wmax orelse std.math.maxInt(u32),
175 | );
176 | const height = std.math.clamp(
177 | h,
178 | sl.wmin orelse 0,
179 | sl.wmax orelse std.math.maxInt(u32),
180 | );
181 |
182 | self.config.width = width;
183 | self.config.height = height;
184 |
185 | if (!self.config.flags.resizable) {
186 | return;
187 | }
188 | return self.owner.platform.window.setSize(self, width, height);
189 | }
190 | pub fn setSizeLimits(self: *Window, wmin: ?u32, wmax: ?u32, hmin: ?u32, hmax: ?u32) void {
191 | std.debug.assert((wmin orelse 0) < (wmax orelse MAX_U32));
192 | std.debug.assert((hmin orelse 0) < (hmax orelse MAX_U32));
193 |
194 | self.config.sizeLimits = .{
195 | .wmin = wmin,
196 | .wmax = wmax,
197 | .hmin = hmin,
198 | .hmax = hmax,
199 | };
200 |
201 | if (!self.config.flags.resizable) {
202 | return;
203 | }
204 |
205 | return self.owner.platform.window.setSizeLimits(self, wmin, wmax, hmin, hmax);
206 | }
207 | pub fn getFramebufferSize(self: *Window, x: ?*u32, y: ?*u32) void {
208 | return self.owner.platform.window.getFramebufferSize(self, x, y);
209 | }
210 | pub fn setVisible(self: *Window, value: bool) void {
211 | if (self.config.flags.hidden == !value) {
212 | return;
213 | }
214 | self.config.flags.hidden = !value;
215 | return self.owner.platform.window.setVisible(self, value);
216 | }
217 | pub fn setTitle(self: *Window, title: []const u8) Error!void {
218 | if (std.mem.eql(u8, title, self.config.title)) {
219 | return;
220 | }
221 | const title_copy = self.owner.allocator.dupe(u8, title) catch |e| {
222 | return self.owner.setError("Cannot copy window title", .{}, e);
223 | };
224 | self.owner.allocator.free(self.config.title);
225 | self.config.title = title_copy;
226 | return self.owner.platform.window.setTitle(self, title);
227 | }
228 | /// The returned string is allocated via the allocator
229 | /// given to `Zwl.init()`.
230 | pub fn getTitle(self: *Window) []const u8 {
231 | return self.config.title;
232 | }
233 | pub fn isFocused(self: *Window) bool {
234 | return self.owner.platform.window.isFocused(self);
235 | }
236 | pub fn setMousePos(self: *Window, x: u32, y: u32) void {
237 | if (self.mouse.lastX == x and
238 | self.mouse.lastY == y) return;
239 | self.mouse = .{
240 | .lastX = @intCast(x),
241 | .lastY = @intCast(y),
242 | };
243 | return self.owner.platform.window.setMousePos(self, x, y);
244 | }
245 | pub fn getMousePos(self: *Window, x: ?*u32, y: ?*u32) void {
246 | return self.owner.platform.window.getMousePos(self, x, y);
247 | }
248 | pub fn setMouseVisible(self: *Window, value: bool) void {
249 | if (self.config.flags.hideMouse == !value) return;
250 | self.config.flags.hideMouse = !value;
251 | return self.owner.platform.window.setMouseVisible(self, value);
252 | }
253 | pub fn getKey(self: *Window, key: Key) bool {
254 | return self.keys[@intFromEnum(key)];
255 | }
256 | pub fn hasFocus(self: *Window) bool {
257 | return self.config.flags.hasFocus;
258 | }
259 | pub fn setFocus(self: *Window) void {
260 | if (self.config.flags.hasFocus) return;
261 | self.config.flags.hasFocus = true;
262 | self.owner.platform.window.setFocus(self);
263 | }
264 | pub fn setMouseConfined(self: *Window, value: bool) void {
265 | self.owner.platform.window.setMouseConfined(self, value);
266 | }
267 | pub fn getButton(self: *Window, button: u8) bool {
268 | return button < self.mouseButtons.len and self.mouseButtons[button];
269 | }
270 | };
271 |
--------------------------------------------------------------------------------
/src/windows/context.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const Zwl = @import("../Zwl.zig");
3 | const internal = @import("init.zig");
4 | const W32 = @import("w32.zig");
5 |
6 | const Window = Zwl.Window;
7 | const Error = Zwl.Error;
8 | const Event = Zwl.Event;
9 |
10 | pub const PFD = W32.PIXELFORMATDESCRIPTOR{
11 | .nVersion = 1,
12 | .dwFlags = W32.PFD_DRAW_TO_WINDOW |
13 | W32.PFD_SUPPORT_OPENGL |
14 | W32.PFD_DOUBLEBUFFER,
15 | .iPixelType = W32.PFD_TYPE_RGBA,
16 | .cColorBits = 24,
17 | .cDepthBits = 8,
18 | .cStencilBits = 0,
19 | .cAuxBuffers = 0,
20 | .iLayerType = 0, //W32.PFD_MAIN_PLANE,
21 | };
22 |
23 | pub const GLContext = struct {
24 | threadlocal var currentContext: ?GLContext = null;
25 |
26 | dc: W32.HDC,
27 | handle: W32.HGLRC,
28 | interval: i32,
29 |
30 | pub fn init(self: *GLContext, lib: *Zwl, window: *Window, config: Zwl.GLContext.Config) Error!void {
31 | const dc = W32.GetDC(window.native.handle) orelse {
32 | return lib.setError("Cannot get device context from window", .{}, Error.Win32);
33 | };
34 | self.dc = dc;
35 |
36 | const format: i32 = if (@as(u56, @bitCast(config.pixelFormat)) != 0) blk: {
37 | if (lib.native.wglChoosePixelFormatARB) |wglChoosePixelFormatARB| {
38 | const attribs = [_:.{ 0, 0 }][2]i32{
39 | .{ W32.WGL_DRAW_TO_WINDOW_ARB, 1 },
40 | .{ W32.WGL_SUPPORT_OPENGL_ARB, 1 },
41 | .{ W32.WGL_DOUBLE_BUFFER_ARB, 1 },
42 | .{ W32.WGL_PIXEL_TYPE_ARB, W32.WGL_TYPE_RGBA_ARB },
43 | .{ W32.WGL_COLOR_BITS_ARB, 24 },
44 | .{ W32.WGL_RED_BITS_ARB, config.pixelFormat.redBits },
45 | .{ W32.WGL_GREEN_BITS_ARB, config.pixelFormat.greenBits },
46 | .{ W32.WGL_BLUE_BITS_ARB, config.pixelFormat.blueBits },
47 | .{ W32.WGL_ALPHA_BITS_ARB, config.pixelFormat.alphaBits },
48 | .{ W32.WGL_STENCIL_BITS_ARB, config.pixelFormat.stencilBits },
49 | .{ W32.WGL_DEPTH_BITS_ARB, config.pixelFormat.depthBits },
50 | .{ W32.WGL_SAMPLE_BUFFERS_ARB, 1 },
51 | .{ W32.WGL_SAMPLES_ARB, config.pixelFormat.samples },
52 | };
53 | var nFormats: u32 = undefined;
54 | var result: i32 = undefined;
55 | if (wglChoosePixelFormatARB(
56 | dc,
57 | &attribs,
58 | null,
59 | 1,
60 | @ptrCast(&result),
61 | &nFormats,
62 | ) == 0) {
63 | return lib.setError("Cannot find suitable pixel format", .{}, Error.Win32);
64 | }
65 | break :blk result;
66 | } else {
67 | return lib.setError("wglChoosePixelFormatARB unavailable while requested specific pixel format", .{}, Error.Win32);
68 | }
69 | } else W32.ChoosePixelFormat(dc, &PFD);
70 |
71 | if (W32.SetPixelFormat(dc, format, &PFD) == 0) {
72 | return lib.setError("Cannot set pixel format for device context: {d}", .{W32.GetLastError()}, Error.Win32);
73 | }
74 |
75 | if (config.version.api == .opengl and lib.native.wglCreateContextAttribsARB == null) {
76 | if (config.forward) {
77 | return lib.setError("Cannot set forward compatibility without WGL_ARB_create_context (unavailable)", .{}, Error.Win32);
78 | }
79 | if (config.profile != .any) {
80 | return lib.setError("Cannot set opengl profile without WGL_ARB_create_context_profile (unavailable)", .{}, Error.Win32);
81 | }
82 | } else if (config.version.api == .opengl_es) {
83 | @panic("OpenGL ES not yet implemented");
84 | }
85 |
86 | if (lib.native.wglCreateContextAttribsARB) |wglCreateContextAttribsARB| {
87 | var attribs: [4:.{ 0, 0 }][2]i32 = undefined;
88 | var index: u32 = 0;
89 | var mask: u32 = 0;
90 | var flags: u32 = 0;
91 |
92 | if (config.version.api == .opengl) {
93 | if (config.forward) {
94 | flags |= W32.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
95 | }
96 |
97 | if (config.profile == .core) {
98 | mask |= W32.WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
99 | } else if (config.profile == .compat) {
100 | mask |= W32.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
101 | }
102 | } else {
103 | @panic("OpenGL ES not yet implemented");
104 | }
105 |
106 | if (config.version.major != 0 or
107 | config.version.minor != 0)
108 | {
109 | std.debug.assert(config.version.major != 0);
110 | attribs[index] = .{ W32.WGL_CONTEXT_MAJOR_VERSION_ARB, config.version.major };
111 | attribs[index + 1] = .{ W32.WGL_CONTEXT_MINOR_VERSION_ARB, config.version.minor };
112 | index += 2;
113 | }
114 |
115 | if (config.debug) {
116 | flags |= W32.WGL_CONTEXT_DEBUG_BIT_ARB;
117 | }
118 |
119 | if (flags != 0) {
120 | attribs[index] = .{ W32.WGL_CONTEXT_FLAGS_ARB, @bitCast(flags) };
121 | index += 1;
122 | }
123 | if (mask != 0) {
124 | attribs[index] = .{ W32.WGL_CONTEXT_PROFILE_MASK_ARB, @bitCast(mask) };
125 | index += 1;
126 | }
127 |
128 | self.handle = wglCreateContextAttribsARB(
129 | dc,
130 | if (config.share) |share| share.native.handle else null,
131 | @ptrCast(&attribs),
132 | ) orelse {
133 | switch (W32.GetLastError()) {
134 | @as(i32, @truncate(0xc0070000)) | W32.ERROR_INVALID_VERSION_ARB => {
135 | if (config.version.api == .opengl) {
136 | return lib.setError(
137 | "Driver does not support OpenGL {d}.{d}",
138 | .{ config.version.major, config.version.minor },
139 | Error.Win32,
140 | );
141 | } else {
142 | return lib.setError(
143 | "Driver does not support OpenGL ES {d}.{d}",
144 | .{ config.version.major, config.version.minor },
145 | Error.Win32,
146 | );
147 | }
148 | },
149 | @as(i32, @truncate(0xc0070000)) | W32.ERROR_INVALID_PROFILE_ARB => {
150 | return lib.setError(
151 | "Driver does not support requested OpenGL profile",
152 | .{},
153 | Error.Win32,
154 | );
155 | },
156 | @as(i32, @truncate(0xc0070000)) | W32.ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB => {
157 | return lib.setError(
158 | "The share context is not compatible with the requested context",
159 | .{},
160 | Error.Win32,
161 | );
162 | },
163 | else => {
164 | if (config.version.api == .opengl) {
165 | return lib.setError(
166 | "Failed to create OpenGL context",
167 | .{},
168 | Error.Win32,
169 | );
170 | } else {
171 | return lib.setError(
172 | "Failed to create OpenGL ES context",
173 | .{},
174 | Error.Win32,
175 | );
176 | }
177 | },
178 | }
179 | };
180 | return;
181 | }
182 |
183 | self.handle = W32.wglCreateContext(dc) orelse {
184 | return lib.setError("Cannot create WGL context", .{}, Error.Win32);
185 | };
186 | errdefer _ = W32.wglDeleteContext(self.handle);
187 |
188 | if (config.share) |share| {
189 | if (W32.wglShareLists(share.native.handle, self.handle) == 0) {
190 | return lib.setError(
191 | "Failed to enable sharing with specified OpenGL context",
192 | .{},
193 | Error.Win32,
194 | );
195 | }
196 | }
197 | }
198 | pub fn deinit(self: *GLContext) void {
199 | _ = W32.wglDeleteContext(self.handle);
200 | }
201 |
202 | pub fn makeCurrent(lib: *Zwl, opt_ctx: ?*Zwl.GLContext) Error!void {
203 | _ = lib;
204 | currentContext = null;
205 | if (opt_ctx) |ctx| {
206 | if (W32.wglMakeCurrent(ctx.native.dc, ctx.native.handle) == 0) {
207 | return ctx.owner.owner.setError("Failed to make GLContext current", .{}, Error.Win32);
208 | }
209 | currentContext = ctx.native;
210 | } else _ = W32.wglMakeCurrent(undefined, null);
211 | }
212 |
213 | pub fn swapBuffers(ctx: *Zwl.GLContext) Error!void {
214 | _ = W32.SwapBuffers(ctx.native.dc);
215 | }
216 |
217 | pub fn swapInterval(lib: *Zwl, interval: i32) Error!void {
218 | if (lib.native.wglSwapIntervalEXT) |wglSwapIntervalEXT| {
219 | if (wglSwapIntervalEXT(interval) == 0) {
220 | return lib.setError("Cannot find current context", .{}, Error.Win32);
221 | }
222 | } else {
223 | return lib.setError("swapInterval requires wglSwapIntervalEXT (unavailable)", .{}, Error.Win32);
224 | }
225 | }
226 | };
227 |
--------------------------------------------------------------------------------
/src/windows/init.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const Zwl = @import("../Zwl.zig");
3 | const W32 = @import("w32.zig");
4 | const window = @import("window.zig");
5 | const event = @import("event.zig");
6 | const context = @import("context.zig");
7 |
8 | const unicode = std.unicode;
9 | const Allocator = std.mem.Allocator;
10 |
11 | const Platform = Zwl.Platform;
12 | const Error = Zwl.Error;
13 | const Key = Zwl.Key;
14 |
15 | var initCount: u32 = 0;
16 |
17 | pub const WND_CLASS_NAME = utf8ToUtf16Z(undefined, "ZWL_WND") catch unreachable;
18 |
19 | pub const KEYCODES: [512]Key = blk: {
20 | var keycodes = [_]Key{.unkown} ** 512;
21 |
22 | keycodes[0x002] = .@"1";
23 | keycodes[0x003] = .@"2";
24 | keycodes[0x004] = .@"3";
25 | keycodes[0x005] = .@"4";
26 | keycodes[0x006] = .@"5";
27 | keycodes[0x007] = .@"6";
28 | keycodes[0x008] = .@"7";
29 | keycodes[0x009] = .@"8";
30 | keycodes[0x00A] = .@"9";
31 | keycodes[0x00B] = .@"0";
32 | keycodes[0x01E] = .a;
33 | keycodes[0x030] = .b;
34 | keycodes[0x02E] = .c;
35 | keycodes[0x020] = .d;
36 | keycodes[0x012] = .e;
37 | keycodes[0x021] = .f;
38 | keycodes[0x022] = .g;
39 | keycodes[0x023] = .h;
40 | keycodes[0x017] = .i;
41 | keycodes[0x024] = .j;
42 | keycodes[0x025] = .k;
43 | keycodes[0x026] = .l;
44 | keycodes[0x032] = .m;
45 | keycodes[0x031] = .n;
46 | keycodes[0x018] = .o;
47 | keycodes[0x019] = .p;
48 | keycodes[0x010] = .q;
49 | keycodes[0x013] = .r;
50 | keycodes[0x01F] = .s;
51 | keycodes[0x014] = .t;
52 | keycodes[0x016] = .u;
53 | keycodes[0x02F] = .v;
54 | keycodes[0x011] = .w;
55 | keycodes[0x02D] = .x;
56 | keycodes[0x015] = .y;
57 | keycodes[0x02C] = .z;
58 |
59 | keycodes[0x028] = .apostrophe;
60 | keycodes[0x02B] = .backslash;
61 | keycodes[0x033] = .comma;
62 | keycodes[0x00D] = .equal;
63 | keycodes[0x029] = .grave_accent;
64 | keycodes[0x01A] = .left_bracket;
65 | keycodes[0x00C] = .minus;
66 | keycodes[0x034] = .period;
67 | keycodes[0x01B] = .right_bracket;
68 | keycodes[0x027] = .semicolon;
69 | keycodes[0x035] = .slash;
70 | keycodes[0x056] = .world_2;
71 |
72 | keycodes[0x00E] = .backspace;
73 | keycodes[0x153] = .delete;
74 | keycodes[0x14F] = .end;
75 | keycodes[0x01C] = .enter;
76 | keycodes[0x001] = .escape;
77 | keycodes[0x147] = .home;
78 | keycodes[0x152] = .insert;
79 | keycodes[0x15D] = .menu;
80 | keycodes[0x151] = .page_down;
81 | keycodes[0x149] = .page_up;
82 | keycodes[0x045] = .pause;
83 | keycodes[0x039] = .space;
84 | keycodes[0x00F] = .tab;
85 | keycodes[0x03A] = .caps_lock;
86 | keycodes[0x145] = .num_lock;
87 | keycodes[0x046] = .scroll_lock;
88 | keycodes[0x03B] = .f1;
89 | keycodes[0x03C] = .f2;
90 | keycodes[0x03D] = .f3;
91 | keycodes[0x03E] = .f4;
92 | keycodes[0x03F] = .f5;
93 | keycodes[0x040] = .f6;
94 | keycodes[0x041] = .f7;
95 | keycodes[0x042] = .f8;
96 | keycodes[0x043] = .f9;
97 | keycodes[0x044] = .f10;
98 | keycodes[0x057] = .f11;
99 | keycodes[0x058] = .f12;
100 | keycodes[0x064] = .f13;
101 | keycodes[0x065] = .f14;
102 | keycodes[0x066] = .f15;
103 | keycodes[0x067] = .f16;
104 | keycodes[0x068] = .f17;
105 | keycodes[0x069] = .f18;
106 | keycodes[0x06A] = .f19;
107 | keycodes[0x06B] = .f20;
108 | keycodes[0x06C] = .f21;
109 | keycodes[0x06D] = .f22;
110 | keycodes[0x06E] = .f23;
111 | keycodes[0x076] = .f24;
112 | keycodes[0x038] = .left_alt;
113 | keycodes[0x01D] = .left_control;
114 | keycodes[0x02A] = .left_shift;
115 | keycodes[0x15B] = .left_super;
116 | keycodes[0x137] = .print_screen;
117 | keycodes[0x138] = .right_alt;
118 | keycodes[0x11D] = .right_control;
119 | keycodes[0x036] = .right_shift;
120 | keycodes[0x15C] = .right_super;
121 | keycodes[0x150] = .down;
122 | keycodes[0x14B] = .left;
123 | keycodes[0x14D] = .right;
124 | keycodes[0x148] = .up;
125 |
126 | keycodes[0x052] = .kp_0;
127 | keycodes[0x04F] = .kp_1;
128 | keycodes[0x050] = .kp_2;
129 | keycodes[0x051] = .kp_3;
130 | keycodes[0x04B] = .kp_4;
131 | keycodes[0x04C] = .kp_5;
132 | keycodes[0x04D] = .kp_6;
133 | keycodes[0x047] = .kp_7;
134 | keycodes[0x048] = .kp_8;
135 | keycodes[0x049] = .kp_9;
136 | keycodes[0x04E] = .kp_add;
137 | keycodes[0x053] = .kp_decimal;
138 | keycodes[0x135] = .kp_divide;
139 | keycodes[0x11C] = .kp_enter;
140 | keycodes[0x059] = .kp_equal;
141 | keycodes[0x037] = .kp_multiply;
142 | keycodes[0x04A] = .kp_subtract;
143 |
144 | break :blk keycodes;
145 | };
146 | pub const SCANCODES: [@intFromEnum(Key.last)]u16 = blk: {
147 | var res = [_]u16{0xFFFF} ** @intFromEnum(Key.last);
148 | for (0..512) |scancode| {
149 | if (KEYCODES[scancode] != .unkown) {
150 | res[@intFromEnum(KEYCODES[scancode])] = scancode;
151 | }
152 | }
153 | break :blk res;
154 | };
155 |
156 | pub const NativeData = struct {
157 | hInstance: W32.HINSTANCE,
158 | /// Used to query WGL extensions
159 | helperWindow: struct {
160 | handle: W32.HWND,
161 | dc: W32.HDC,
162 | glrc: W32.HGLRC,
163 | },
164 | wglCreateContextAttribsARB: ?*const fn (hDC: W32.HDC, hShareContext: ?W32.HGLRC, attribList: [*:.{0,0}]const [2]i32) callconv(W32.WINAPI) ?W32.HGLRC,
165 | wglChoosePixelFormatARB: ?*const fn (hDC: W32.HDC, piAttribIList: ?[*:.{0,0}]const [2]i32, pfAttribFList: ?[*]const f32, nMaxFormats: u32, piFormats: [*]i32, nNumFormats: *u32) callconv(W32.WINAPI) W32.BOOL,
166 | wglSwapIntervalEXT: ?*const fn (interval: i32) callconv(W32.WINAPI) W32.BOOL,
167 | keynames: [@intFromEnum(Key.last)][10:0]u8,
168 | };
169 |
170 | pub inline fn utf8ToUtf16(allocator: Allocator, utf8: []const u8) error{ InvalidUtf8, OutOfMemory }![]const u16 {
171 | if (@inComptime()) comptime {
172 | return unicode.utf8ToUtf16LeStringLiteral(utf8);
173 | } else {
174 | return unicode.utf8ToUtf16LeAlloc(allocator, utf8);
175 | }
176 | }
177 |
178 | pub inline fn utf8ToUtf16Z(allocator: Allocator, utf8: []const u8) error{ InvalidUtf8, OutOfMemory }![:0]const u16 {
179 | if (@inComptime()) comptime {
180 | return unicode.utf8ToUtf16LeStringLiteral(utf8);
181 | } else {
182 | return unicode.utf8ToUtf16LeAllocZ(allocator, utf8);
183 | }
184 | }
185 |
186 | pub inline fn utf16ToUtf8(allocator: Allocator, utf16: []const u16) error{ InvalidUtf16, OutOfMemory }![]const u16 {
187 | return unicode.utf16LeToUtf8Alloc(allocator, utf16) catch error.InvalidUtf16;
188 | }
189 |
190 | pub inline fn utf16ToUtf8Z(allocator: Allocator, utf16: []const u16) error{ InvalidUtf16, OutOfMemory }![:0]const u16 {
191 | return unicode.utf16LeToUtf8AllocZ(allocator, utf16) catch error.InvalidUtf16;
192 | }
193 |
194 | pub fn updateKeyNames(native: *NativeData) void {
195 | var state = [_]u8{0} ** 256;
196 | @memset(&native.keynames, [_:0]u8{0} ** (@sizeOf(@TypeOf(native.keynames[0])) - 1));
197 | for (@intFromEnum(Key.space)..@intFromEnum(Key.last)) |key_int| {
198 | const scancode = SCANCODES[key_int];
199 | if (scancode == 0xFFFF) continue;
200 |
201 | const vks = [_]W32.UINT{ W32.VK_NUMPAD0, W32.VK_NUMPAD1, W32.VK_NUMPAD2, W32.VK_NUMPAD3, W32.VK_NUMPAD4, W32.VK_NUMPAD5, W32.VK_NUMPAD6, W32.VK_NUMPAD7, W32.VK_NUMPAD8, W32.VK_NUMPAD9, W32.VK_DECIMAL, W32.VK_DIVIDE, W32.VK_MULTIPLY, W32.VK_SUBTRACT, W32.VK_ADD };
202 |
203 | const vk = if (key_int >= @intFromEnum(Key.kp_0) and key_int <= @intFromEnum(Key.kp_add))
204 | vks[key_int - @intFromEnum(Key.kp_0)]
205 | else
206 | W32.MapVirtualKeyW(scancode, W32.MAPVK_VSC_TO_VK);
207 |
208 | var chars: [16]u16 = undefined;
209 | var length = W32.ToUnicode(
210 | vk,
211 | scancode,
212 | &state,
213 | @ptrCast(&chars),
214 | chars.len,
215 | 0,
216 | );
217 | if (length == -1) {
218 | length = W32.ToUnicode(
219 | vk,
220 | scancode,
221 | &state,
222 | @ptrCast(&chars),
223 | chars.len + 1,
224 | 0,
225 | );
226 | }
227 | if (length < 1) return;
228 |
229 | const size = std.unicode.utf16LeToUtf8(
230 | &native.keynames[key_int],
231 | std.mem.span(@as([*:0]const u16, @ptrCast(&chars))),
232 | ) catch continue;
233 | native.keynames[key_int][size] = 0;
234 | }
235 | }
236 |
237 | pub fn init(lib: *Zwl, _: Zwl.Config) Error!void {
238 | const native = &lib.native;
239 |
240 | const hInstance: W32.HINSTANCE = @ptrCast(W32.GetModuleHandleW(null));
241 | native.hInstance = hInstance;
242 |
243 | if (initCount == 0 and W32.RegisterClassExW(&.{
244 | .style = W32.CS_HREDRAW | W32.CS_VREDRAW | W32.CS_OWNDC,
245 | .lpfnWndProc = &window.windowProc,
246 | .hInstance = hInstance,
247 | .hCursor = W32.LoadCursorW(null, W32.IDC_ARROW),
248 | .lpszClassName = WND_CLASS_NAME.ptr,
249 | }) == 0) return lib.setError("Cannot register window class", .{}, Error.Win32);
250 | initCount += 1;
251 |
252 | const helperWindow = &native.helperWindow;
253 | const hWindow = W32.CreateWindowExW(
254 | 0,
255 | WND_CLASS_NAME.ptr,
256 | comptime (utf8ToUtf16Z(undefined, "ZWL helper window") catch unreachable).ptr,
257 | 0,
258 | 0,
259 | 0,
260 | 1,
261 | 1,
262 | null,
263 | null,
264 | hInstance,
265 | null,
266 | ) orelse {
267 | return lib.setError("Cannot create helper window", .{}, Error.Win32);
268 | };
269 | errdefer _ = W32.DestroyWindow(hWindow);
270 | _ = W32.ShowWindow(hWindow, W32.SW_HIDE);
271 | helperWindow.handle = hWindow;
272 |
273 | { // create helper window opengl context
274 | const dc = W32.GetDC(hWindow) orelse {
275 | return lib.setError("Cannot get device context from helper window", .{}, Error.Win32);
276 | };
277 | helperWindow.dc = dc;
278 |
279 | if (W32.SetPixelFormat(dc, W32.ChoosePixelFormat(dc, &context.PFD), &context.PFD) == 0) {
280 | return lib.setError("Cannot set pixel format for device context", .{}, Error.Win32);
281 | }
282 |
283 | const glrc = W32.wglCreateContext(dc) orelse {
284 | return lib.setError("Cannot create WGL context", .{}, Error.Win32);
285 | };
286 | errdefer _ = W32.wglDeleteContext(glrc);
287 | helperWindow.glrc = glrc;
288 |
289 | _ = W32.wglMakeCurrent(dc, glrc);
290 |
291 | native.wglCreateContextAttribsARB = @ptrCast(W32.wglGetProcAddress("wglCreateContextAttribsARB"));
292 | native.wglChoosePixelFormatARB = @ptrCast(W32.wglGetProcAddress("wglChoosePixelFormatARB"));
293 | native.wglSwapIntervalEXT = @ptrCast(W32.wglGetProcAddress("wglSwapIntervalEXT"));
294 |
295 | _ = W32.wglMakeCurrent(undefined, null);
296 | }
297 |
298 | updateKeyNames(native);
299 | }
300 |
301 | pub fn deinit(lib: *Zwl) void {
302 | initCount -= 1;
303 | _ = W32.wglDeleteContext(lib.native.helperWindow.glrc);
304 | _ = W32.DestroyWindow(lib.native.helperWindow.handle);
305 | if (initCount == 0) {
306 | _ = W32.UnregisterClassW(WND_CLASS_NAME.ptr, lib.native.hInstance);
307 | }
308 | }
309 |
310 | pub fn keyName(lib: *const Zwl, key: Key) [:0]const u8 {
311 | return std.mem.span(@as([*:0]const u8, @ptrCast(&lib.native.keynames[@intFromEnum(key)])));
312 | }
313 |
--------------------------------------------------------------------------------
/src/windows/window.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const Zwl = @import("../Zwl.zig");
3 | const internal = @import("init.zig");
4 | const W32 = @import("w32.zig");
5 | const event = @import("event.zig");
6 |
7 | const assert = std.debug.assert;
8 | const math = std.math;
9 | const clamp = math.clamp;
10 |
11 | const Error = Zwl.Error;
12 | const Window = Zwl.Window;
13 | const Event = Zwl.Event;
14 | const Key = Zwl.Key;
15 |
16 | pub const WND_PTR_PROP_NAME = internal.utf8ToUtf16Z(undefined, "ZWL") catch unreachable;
17 |
18 | const MAX_U32 = math.maxInt(u32);
19 |
20 | pub const NativeWindow = struct {
21 | handle: W32.HWND,
22 | dc: W32.HDC,
23 |
24 | pub fn init(self: *NativeWindow, lib: *Zwl, config: Window.Config) Error!void {
25 | const window: *Window = @fieldParentPtr("native", self);
26 | var aa = std.heap.ArenaAllocator.init(window.owner.allocator);
27 | defer _ = aa.reset(.free_all);
28 | const arena = aa.allocator();
29 |
30 | const wideTitle = internal.utf8ToUtf16Z(arena, config.title) catch |e| {
31 | return lib.setError("Cannot create wide title for Win32", .{}, e);
32 | };
33 |
34 | const realFlags = blk: {
35 | const sizeLimits = config.sizeLimits;
36 | var flags = config.flags;
37 | if (!flags.noDecoration and
38 | sizeLimits.wmin != null and sizeLimits.wmax != null and
39 | sizeLimits.hmin != null and sizeLimits.hmax != null and
40 | sizeLimits.wmin == sizeLimits.wmax and
41 | sizeLimits.hmin == sizeLimits.hmax)
42 | {
43 | flags.resizable = false;
44 | }
45 | break :blk flags;
46 | };
47 | const style = windowFlagsToNative(realFlags);
48 | const exStyle = windowFlagsToExNative(config.flags);
49 |
50 | const width, const height = getWindowFullsize(
51 | style,
52 | exStyle,
53 | config.width,
54 | config.height,
55 | );
56 |
57 | const handle = W32.CreateWindowExW(
58 | exStyle,
59 | internal.WND_CLASS_NAME.ptr,
60 | wideTitle.ptr,
61 | style,
62 | @bitCast(config.x.toNumber(@bitCast(W32.CW_USEDEFAULT))),
63 | @bitCast(config.y.toNumber(@bitCast(W32.CW_USEDEFAULT))),
64 | @intCast(width),
65 | @intCast(height),
66 | null,
67 | null,
68 | lib.native.hInstance,
69 | null,
70 | ) orelse {
71 | return lib.setError("Cannot create window", .{}, Error.Win32);
72 | };
73 | errdefer _ = W32.DestroyWindow(handle);
74 |
75 | if (W32.SetPropW(handle, WND_PTR_PROP_NAME.ptr, @ptrCast(window)) == 0) {
76 | return lib.setError("Cannot set window property", .{}, Error.Win32);
77 | }
78 |
79 | self.handle = handle;
80 | self.dc = W32.GetDC(handle) orelse {
81 | return lib.setError("Cannot retreive window's device context", .{}, Error.Win32);
82 | };
83 |
84 | window.setMouseVisible(!config.flags.hideMouse);
85 | }
86 |
87 | pub fn deinit(self: *NativeWindow) void {
88 | _ = W32.ReleaseDC(self.handle, self.dc);
89 | _ = W32.DestroyWindow(self.handle);
90 | }
91 |
92 | pub fn createMessageBox(lib: *Zwl, config: Window.MBConfig) Error!Window.MBButton {
93 | const wideTitle = internal.utf8ToUtf16Z(lib.allocator, config.title) catch |e| {
94 | return lib.setError("Cannot create wide title for Win32", .{}, e);
95 | };
96 | defer lib.allocator.free(wideTitle);
97 | const wideText = internal.utf8ToUtf16Z(lib.allocator, config.text) catch |e| {
98 | return lib.setError("Cannot create wide text for Win32", .{}, e);
99 | };
100 | defer lib.allocator.free(wideText);
101 |
102 | var uType: W32.UINT = 0;
103 | uType |= switch (config.mode) {
104 | .ok => 0,
105 | .okCancel => 1,
106 | .abortRetryIgnore => 2,
107 | .yesNoCancel => 3,
108 | .yesNo => 4,
109 | .retryCancel => 5,
110 | .cancelTryContinue => 6,
111 | };
112 | uType |= switch (config.icon) {
113 | .none => 0,
114 | .@"error" => 0x10,
115 | .question => 0x20,
116 | .warning => 0x30,
117 | .information => 0x40,
118 | };
119 |
120 | const ret = W32.MessageBoxW(
121 | if (config.parent) |p| p.native.handle else null,
122 | wideText.ptr,
123 | wideTitle.ptr,
124 | uType,
125 | );
126 | return switch (ret) {
127 | 0 => lib.setError("Cannot create message box", .{}, Error.Win32),
128 | 1 => .ok,
129 | 2 => .cancel,
130 | 3 => .abort,
131 | 4 => .retry,
132 | 5 => .ignore,
133 | 6 => .yes,
134 | 7 => .no,
135 | 11 => .@"continue",
136 | 10 => .tryAgain,
137 | else => unreachable,
138 | };
139 | }
140 |
141 | pub fn getPosition(window: *Window, x: ?*u32, y: ?*u32) void {
142 | var pt: W32.POINT = .{};
143 | _ = W32.ClientToScreen(window.native.handle, &pt);
144 |
145 | {
146 | @setRuntimeSafety(false);
147 | if (x) |_| x.?.* = @bitCast(pt.x);
148 | if (y) |_| y.?.* = @bitCast(pt.y);
149 | }
150 | }
151 |
152 | pub fn setPosition(window: *Window, x: u32, y: u32) void {
153 | window.config.x = .{ .pos = x };
154 | window.config.y = .{ .pos = y };
155 |
156 | var rect = W32.RECT{
157 | .left = @bitCast(x),
158 | .top = @bitCast(y),
159 | .right = @bitCast(x),
160 | .bottom = @bitCast(y),
161 | };
162 | _ = W32.AdjustWindowRectEx(
163 | &rect,
164 | windowFlagsToNative(window.config.flags),
165 | W32.FALSE,
166 | windowFlagsToExNative(window.config.flags),
167 | );
168 |
169 | _ = W32.SetWindowPos(
170 | window.native.handle,
171 | null,
172 | rect.bottom,
173 | rect.top,
174 | 0,
175 | 0,
176 | W32.SWP_NOACTIVATE | W32.SWP_NOZORDER | W32.SWP_NOSIZE,
177 | );
178 | }
179 |
180 | pub fn setSize(window: *Window, w: u32, h: u32) void {
181 | var rect = W32.RECT{
182 | .left = 0,
183 | .top = 0,
184 | .right = @intCast(w),
185 | .bottom = @intCast(h),
186 | };
187 |
188 | _ = W32.AdjustWindowRectEx(
189 | &rect,
190 | windowFlagsToNative(window.config.flags),
191 | W32.FALSE,
192 | windowFlagsToExNative(window.config.flags),
193 | );
194 |
195 | _ = W32.SetWindowPos(
196 | window.native.handle,
197 | W32.HWND_TOP,
198 | 0,
199 | 0,
200 | rect.right - rect.left,
201 | rect.bottom - rect.top,
202 | W32.SWP_NOACTIVATE | W32.SWP_NOOWNERZORDER | W32.SWP_NOMOVE | W32.SWP_NOZORDER,
203 | );
204 | }
205 |
206 | pub fn setSizeLimits(
207 | window: *Window,
208 | wmin: ?u32,
209 | wmax: ?u32,
210 | hmin: ?u32,
211 | hmax: ?u32,
212 | ) void {
213 | if ((wmin == null and hmin == null) and
214 | (wmax == null or hmax == null))
215 | {
216 | return;
217 | }
218 |
219 | var area: W32.RECT = undefined;
220 |
221 | _ = W32.GetWindowRect(window.native.handle, &area);
222 |
223 | _ = W32.MoveWindow(
224 | window.native.handle,
225 | area.left,
226 | area.top,
227 | area.right - area.left,
228 | area.bottom - area.top,
229 | W32.TRUE,
230 | );
231 | }
232 |
233 | pub fn getFramebufferSize(window: *Window, w: ?*u32, h: ?*u32) void {
234 | var area: W32.RECT = .{};
235 | _ = W32.GetClientRect(window.native.handle, &area);
236 |
237 | {
238 | @setRuntimeSafety(false);
239 | if (w) |_| w.?.* = @bitCast(area.right);
240 | if (h) |_| h.?.* = @bitCast(area.bottom);
241 | }
242 | }
243 |
244 | pub fn setVisible(window: *Window, value: bool) void {
245 | _ = W32.ShowWindow(window.native.handle, W32.SW_SHOWNA * @intFromBool(value));
246 | }
247 |
248 | pub fn setTitle(window: *Window, title: []const u8) Error!void {
249 | const wideTitle = internal.utf8ToUtf16Z(window.owner.allocator, title) catch |e| {
250 | return window.owner.setError("Cannot create wide title for Win32", .{}, e);
251 | };
252 | defer window.owner.allocator.free(wideTitle);
253 |
254 | _ = W32.SetWindowTextW(window.native.handle, wideTitle.ptr);
255 | }
256 |
257 | pub fn isFocused(window: *Window) bool {
258 | return window.native.handle == W32.GetActiveWindow();
259 | }
260 |
261 | pub fn getMousePos(window: *Window, x: ?*u32, y: ?*u32) void {
262 | var pos: W32.POINT = undefined;
263 | if (W32.GetCursorPos(&pos) != 0) {
264 | _ = W32.ScreenToClient(window.native.handle, &pos);
265 |
266 | if (x) |xp| xp.* = @bitCast(pos.x);
267 | if (y) |yp| yp.* = @bitCast(pos.y);
268 | }
269 | }
270 |
271 | pub fn setMousePos(window: *Window, x: u32, y: u32) void {
272 | var pos: W32.POINT = .{ .x = @bitCast(x), .y = @bitCast(y) };
273 | _ = W32.ClientToScreen(window.native.handle, &pos);
274 | _ = W32.SetCursorPos(pos.x, pos.y);
275 | }
276 |
277 | pub fn setMouseVisible(window: *Window, value: bool) void {
278 | _ = window;
279 | _ = W32.ShowCursor(@intFromBool(value));
280 | }
281 |
282 | pub fn setFocus(window: *Window) void {
283 | _ = W32.SetFocus(window.native.handle);
284 | }
285 |
286 | pub fn setMouseConfined(window: *Window, value: bool) void {
287 | if (value) {
288 | var rect: W32.RECT = .{
289 | .right = @intCast(window.config.width),
290 | .bottom = @intCast(window.config.height),
291 | };
292 | _ = W32.ClientToScreen(window.native.handle, @ptrCast(&rect));
293 | _ = W32.ClientToScreen(window.native.handle, @ptrCast(&rect.right));
294 | _ = W32.ClipCursor(&rect);
295 | } else {
296 | _ = W32.ClipCursor(null);
297 | }
298 | }
299 |
300 | pub fn freeMouse(window: *Window) void {
301 | _ = window;
302 | _ = W32.ClipCursor(null);
303 | }
304 |
305 | pub fn getDC(window: *NativeWindow) ?W32.HDC {
306 | return W32.GetDC(window.handle);
307 | }
308 | };
309 |
310 | pub fn windowProc(wind: W32.HWND, msg: W32.UINT, wp: W32.WPARAM, lp: W32.LPARAM) callconv(W32.CALLBACK) W32.LRESULT {
311 | const window: *Window = @ptrCast(@alignCast(W32.GetPropW(wind, WND_PTR_PROP_NAME.ptr) orelse {
312 | return W32.DefWindowProcW(wind, msg, wp, lp);
313 | }));
314 |
315 | return windowProcInner(wind, window, msg, wp, lp) catch |e| blk: {
316 | event.pollingError = e;
317 | break :blk 1;
318 | };
319 | }
320 |
321 | fn windowProcInner(wind: W32.HWND, window: *Window, msg: W32.UINT, wp: W32.WPARAM, lp: W32.LPARAM) Error!W32.LRESULT {
322 | const lib = window.owner;
323 |
324 | switch (msg) {
325 | W32.WM_CLOSE => {
326 | try event.queueEvent(lib, .{ .windowClosed = window });
327 | },
328 | W32.WM_SIZE => {
329 | const width: u16 = @truncate(@as(u64, @bitCast(lp)) & 0xFFFF);
330 | const height: u16 = @truncate(@as(u64, @bitCast(lp >> 16)) & 0xFFFF);
331 | try event.queueEvent(lib, .{ .windowResized = .{
332 | .window = window,
333 | .width = width,
334 | .height = height,
335 | } });
336 | window.config.width = width;
337 | window.config.height = height;
338 | },
339 | W32.WM_MOUSEMOVE => {
340 | const x: u16 = @truncate(@as(u64, @bitCast(lp)) & 0xFFFF);
341 | const y: u16 = @truncate(@as(u64, @bitCast(lp >> 16)) & 0xFFFF);
342 |
343 | const dx = @as(i16, @bitCast(x)) - @as(i16, @bitCast(window.mouse.lastX));
344 | const dy = @as(i16, @bitCast(y)) - @as(i16, @bitCast(window.mouse.lastY));
345 | try event.queueEvent(lib, .{ .mouseMoved = .{
346 | .window = window,
347 | .x = x,
348 | .y = y,
349 | .dx = dx,
350 | .dy = dy,
351 | } });
352 |
353 | window.mouse.lastX = x;
354 | window.mouse.lastY = y;
355 | },
356 | W32.WM_LBUTTONDOWN,
357 | W32.WM_LBUTTONUP,
358 | W32.WM_RBUTTONDOWN,
359 | W32.WM_RBUTTONUP,
360 | W32.WM_MBUTTONDOWN,
361 | W32.WM_MBUTTONUP,
362 | W32.WM_XBUTTONDOWN,
363 | W32.WM_XBUTTONUP,
364 | => {
365 | const button: u8 = switch (msg) {
366 | W32.WM_LBUTTONDOWN, W32.WM_LBUTTONUP => 0,
367 | W32.WM_RBUTTONDOWN, W32.WM_RBUTTONUP => 2,
368 | W32.WM_MBUTTONDOWN, W32.WM_MBUTTONUP => 1,
369 | W32.WM_XBUTTONDOWN, W32.WM_XBUTTONUP => @truncate(((wp >> 16) & 0xFFFF) + 2),
370 | else => unreachable,
371 | };
372 | const pressed: bool = switch (msg) {
373 | W32.WM_LBUTTONDOWN, W32.WM_RBUTTONDOWN, W32.WM_MBUTTONDOWN, W32.WM_XBUTTONDOWN => true,
374 | W32.WM_LBUTTONUP, W32.WM_RBUTTONUP, W32.WM_MBUTTONUP, W32.WM_XBUTTONUP => false,
375 | else => unreachable,
376 | };
377 | const mods = getKeyMods();
378 | window.mouseButtons[button] = pressed;
379 | try event.queueEvent(lib, .{ .mouseButton = .{
380 | .window = window,
381 | .clicked = pressed,
382 | .button = button,
383 | .mods = .{
384 | .control = mods.control,
385 | .shift = mods.shift,
386 | },
387 | } });
388 | },
389 | W32.WM_MOUSEWHEEL => {
390 | try event.queueEvent(lib, .{ .mouseWheel = .{
391 | .window = window,
392 | .x = 0,
393 | .y = @as(f32, @floatFromInt((wp >> 16) & 0xFFFF)) / 120,
394 | .mods = .{
395 | .control = wp & 0x08 != 0,
396 | .shift = wp & 0x04 != 0,
397 | },
398 | } });
399 | },
400 | W32.WM_MOUSEHWHEEL => {
401 | try event.queueEvent(lib, .{ .mouseWheel = .{
402 | .window = window,
403 | .x = @as(f32, @floatFromInt((wp >> 16) & 0xFFFF)) / 120,
404 | .y = 0,
405 | .mods = .{
406 | .control = wp & 0x08 != 0,
407 | .shift = wp & 0x04 != 0,
408 | },
409 | } });
410 | },
411 | W32.WM_GETMINMAXINFO => {
412 | if (!window.config.flags.resizable) {
413 | return 0;
414 | }
415 |
416 | const mmi: *W32.MINMAXINFO = @ptrFromInt(@as(u64, @bitCast(lp)));
417 | const config = window.config;
418 | const sl = config.sizeLimits;
419 |
420 | // USER_DEFAULT_SCREEN_DPI
421 | // const dpi: W32.UINT = 96;
422 |
423 | const xoff, const yoff = getWindowFullsize(
424 | windowFlagsToNative(window.config.flags),
425 | windowFlagsToExNative(window.config.flags),
426 | 0,
427 | 0,
428 | );
429 |
430 | if (sl.wmin) |wmin| {
431 | mmi.ptMinTrackSize.x = @bitCast(wmin + xoff);
432 | }
433 | if (sl.wmax) |wmax| {
434 | mmi.ptMinTrackSize.x = @bitCast(wmax + xoff);
435 | }
436 | if (sl.hmin) |hmin| {
437 | mmi.ptMinTrackSize.y = @bitCast(hmin + yoff);
438 | }
439 | if (sl.hmax) |hmax| {
440 | mmi.ptMinTrackSize.y = @bitCast(hmax + yoff);
441 | }
442 | },
443 | W32.WM_KEYDOWN,
444 | W32.WM_KEYUP,
445 | W32.WM_SYSKEYDOWN,
446 | W32.WM_SYSKEYUP,
447 | => blk: {
448 | const lp_hiword = @as(u64, @bitCast(lp >> 16)) & 0xFFFF;
449 |
450 | var scancode: u32 = @truncate(lp_hiword & 0x01FF);
451 | var action: Key.Action = if (lp_hiword & 0x8000 != 0)
452 | .release
453 | else
454 | .press;
455 | const mods = getKeyMods();
456 |
457 | if (scancode == 0) {
458 | scancode = @bitCast(W32.MapVirtualKeyW(@truncate(wp), 0));
459 | }
460 |
461 | scancode = switch (scancode) {
462 | 0x54 => 0x137,
463 | 0x146 => 0x45,
464 | 0x136 => 0x36,
465 | else => scancode,
466 | };
467 |
468 | var key = internal.KEYCODES[scancode];
469 |
470 | if (wp == W32.VK_CONTROL) {
471 | if (lp_hiword & 0x0100 != 0) {
472 | key = .right_control;
473 | } else {
474 | var next: W32.MSG = undefined;
475 | const time = W32.GetMessageTime();
476 |
477 | if (W32.PeekMessageW(&next, null, 0, 0, W32.PM_NOREMOVE) != 0) {
478 | if (next.message == W32.WM_KEYDOWN or
479 | next.message == W32.WM_SYSKEYDOWN or
480 | next.message == W32.WM_KEYUP or
481 | next.message == W32.WM_SYSKEYUP)
482 | {
483 | if (next.wParam == 0x12 and
484 | @as(u64, @bitCast(next.lParam >> 16)) & 0x0100 != 0 and
485 | next.time == time)
486 | {
487 | break :blk;
488 | }
489 | }
490 | }
491 |
492 | key = .left_control;
493 | }
494 | } else if (wp == W32.VK_PROCESSKEY) {
495 | break :blk;
496 | }
497 |
498 | var repeated: bool = false;
499 |
500 | if (action == .release and !window.keys[@intFromEnum(key)]) {
501 | break :blk;
502 | }
503 |
504 | if (action == .press and window.keys[@intFromEnum(key)]) {
505 | repeated = true;
506 | }
507 |
508 | window.keys[@intFromEnum(key)] = action == .press;
509 |
510 | if (repeated)
511 | action = .repeat;
512 | if (action == .release and wp == W32.VK_SHIFT) {
513 | try event.queueEvent(lib, .{ .key = .{
514 | .window = window,
515 | .key = .left_shift,
516 | .action = action,
517 | .mods = mods,
518 | } });
519 | try event.queueEvent(lib, .{ .key = .{
520 | .window = window,
521 | .key = .right_shift,
522 | .action = action,
523 | .mods = mods,
524 | } });
525 | } else if (wp == W32.VK_SNAPSHOT) {
526 | try event.queueEvent(lib, .{ .key = .{
527 | .window = window,
528 | .key = key,
529 | .action = .press,
530 | .mods = mods,
531 | } });
532 | try event.queueEvent(lib, .{ .key = .{
533 | .window = window,
534 | .key = key,
535 | .action = .release,
536 | .mods = mods,
537 | } });
538 | } else {
539 | try event.queueEvent(lib, .{ .key = .{
540 | .window = window,
541 | .key = key,
542 | .action = action,
543 | .mods = mods,
544 | } });
545 | }
546 | },
547 | W32.WM_SETFOCUS, W32.WM_KILLFOCUS => {
548 | const status = msg == W32.WM_SETFOCUS;
549 | window.config.flags.hasFocus = status;
550 | try event.queueEvent(lib, .{ .windowFocused = .{
551 | .window = window,
552 | .gained = status,
553 | } });
554 | },
555 | W32.WM_INPUTLANGCHANGE => {
556 | internal.updateKeyNames(&lib.native);
557 | },
558 | else => {},
559 | }
560 |
561 | return W32.DefWindowProcW(wind, msg, wp, lp);
562 | }
563 | fn getWindowFullsize(
564 | style: W32.DWORD,
565 | exStyle: W32.DWORD,
566 | contentWidth: u32,
567 | contentHeight: u32,
568 | ) struct { u32, u32 } {
569 | var rect: W32.RECT = .{
570 | .left = 0,
571 | .top = 0,
572 | .right = @intCast(contentWidth),
573 | .bottom = @intCast(contentHeight),
574 | };
575 |
576 | _ = W32.AdjustWindowRectEx(&rect, style, W32.FALSE, exStyle);
577 |
578 | return .{
579 | @bitCast(rect.right - rect.left),
580 | @bitCast(rect.bottom - rect.top),
581 | };
582 | }
583 |
584 | pub fn getKeyMods() Key.Mods {
585 | var mods: Key.Mods = .{};
586 |
587 | if (W32.GetKeyState(0x10) & 0x8000 != 0)
588 | mods.shift = true;
589 | if (W32.GetKeyState(0x11) & 0x8000 != 0)
590 | mods.control = true;
591 | if (W32.GetKeyState(0x12) & 0x8000 != 0)
592 | mods.alt = true;
593 | if (W32.GetKeyState(0x5B) & 0x8000 != 0 and
594 | W32.GetKeyState(0x5C) & 0x8000 != 0)
595 | mods.super = true;
596 | if (W32.GetKeyState(0x14) & 1 != 0)
597 | mods.capsLock = true;
598 | if (W32.GetKeyState(0x90) & 1 != 0)
599 | mods.numLock = true;
600 |
601 | return mods;
602 | }
603 |
604 | fn windowFlagsToNative(flags: Window.Flags) W32.DWORD {
605 | var style = W32.WS_CLIPSIBLINGS | W32.WS_CLIPCHILDREN;
606 |
607 | if (flags.fullscreen) {
608 | style |= W32.WS_POPUP;
609 | } else {
610 | style |= W32.WS_SYSMENU | W32.WS_MINIMIZEBOX;
611 |
612 | if (flags.noDecoration) {
613 | style |= W32.WS_POPUP;
614 | } else {
615 | style |= W32.WS_CAPTION;
616 |
617 | if (flags.resizable) {
618 | style |= W32.WS_MAXIMIZEBOX | W32.WS_THICKFRAME;
619 | }
620 | }
621 | }
622 |
623 | return style;
624 | }
625 |
626 | fn windowFlagsToExNative(flags: Window.Flags) W32.DWORD {
627 | var style = W32.WS_EX_APPWINDOW;
628 |
629 | if (flags.fullscreen or flags.floating) {
630 | style |= W32.WS_EX_TOPMOST;
631 | }
632 |
633 | return style;
634 | }
635 |
--------------------------------------------------------------------------------
/src/windows/w32.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const builtin = @import("builtin");
3 |
4 | pub const CALLBACK: std.builtin.CallingConvention = if (builtin.cpu.arch == .x86) .Stdcall else .C;
5 | pub const WINAPI: std.builtin.CallingConvention = if (builtin.cpu.arch == .x86) .Stdcall else .C;
6 | pub const WINAPIV: std.builtin.CallingConvention = .C;
7 | pub const APIENTRY: std.builtin.CallingConvention = WINAPI;
8 | pub const APIPRIVATE: std.builtin.CallingConvention = if (builtin.cpu.arch == .x86) .Stdcall else .C;
9 | pub const PASCAL: std.builtin.CallingConvention = if (builtin.cpu.arch == .x86) .Stdcall else .C;
10 |
11 | pub const BOOL = i32;
12 | pub const BYTE = u8;
13 | pub const WORD = i16;
14 | pub const SHORT = u16;
15 | pub const ATOM = WORD;
16 | pub const DWORD = i32;
17 | pub const INT = i32;
18 | pub const UINT = u32;
19 | pub const INT_PTR = u64;
20 | pub const LONG = i32;
21 | pub const ULONG = i32;
22 | pub const LONG_PTR = i64;
23 | pub const ULONG_PTR = u64;
24 | pub const LRESULT = LONG_PTR;
25 | pub const LPARAM = LONG_PTR;
26 | pub const WPARAM = INT_PTR;
27 | pub const LPVOID = *anyopaque;
28 | pub const LPCWSTR = [*:0]align(1) const u16;
29 | pub const LPWSTR = [*:0]u16;
30 | pub const HANDLE = *anyopaque;
31 | pub const HINSTANCE = *opaque {};
32 | pub const HMODULE = *opaque {};
33 | pub const HWND = *opaque {};
34 | pub const HICON = *opaque {};
35 | pub const HBRUSH = *opaque {};
36 | pub const HCURSOR = *opaque {};
37 | pub const HDC = *opaque {};
38 | pub const HGLRC = *opaque {};
39 | pub const WNDPROC = *const fn (hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(CALLBACK) LRESULT;
40 | pub const PFTASKDIALOGCALLBACK = *const fn (hWnd: HWND, msg: UINT, wParam: WPARAM, lParam: LPARAM, lprefData: LONG_PTR) callconv(CALLBACK) HRESULT;
41 |
42 | pub const FALSE: BOOL = 0;
43 | pub const TRUE: BOOL = 1;
44 |
45 | pub const HWND_NOTOPMOST: HWND = @ptrFromInt(@as(usize, @truncate(-2)));
46 | pub const HWND_TOPMOSt: HWND = @ptrFromInt(@as(usize, @truncate(-1)));
47 | pub const HWND_TOP: ?HWND = @ptrFromInt(0);
48 | pub const HWND_BOTTOM: HWND = @ptrFromInt(1);
49 | pub const HWND_BROADCAST: HWND = @ptrFromInt(0xFFFF);
50 |
51 | pub const SWP_NOSIZE: UINT = 0x0001;
52 | pub const SWP_NOMOVE: UINT = 0x0002;
53 | pub const SWP_NOZORDER: UINT = 0x0004;
54 | pub const SWP_NOREDRAW: UINT = 0x0008;
55 | pub const SWP_NOACTIVATE: UINT = 0x0010;
56 | pub const SWP_FRAMECHANGED: UINT = 0x0020;
57 | pub const SWP_SHOWWINDOW: UINT = 0x0040;
58 | pub const SWP_HIDEWINDOW: UINT = 0x0080;
59 | pub const SWP_NOCOPYBITS: UINT = 0x0100;
60 | pub const SWP_NOOWNERZORDER: UINT = 0x0200;
61 | pub const SWP_NOSENDCHANGING: UINT = 0x0400;
62 | pub const SWP_DRAWFRAME: UINT = SWP_FRAMECHANGED;
63 | pub const SWP_NOREPOSITION: UINT = SWP_NOOWNERZORDER;
64 | pub const SWP_DEFERERASE: UINT = 0x2000;
65 | pub const SWP_ASYNCWINDOWPOS: UINT = 0x4000;
66 |
67 | pub const CW_USEDEFAULT: i32 = @truncate(0x80000000);
68 |
69 | pub const WS_OVERLAPPED: DWORD = 0x00000000;
70 | pub const WS_TILED: DWORD = 0x00000000;
71 | pub const WS_MAXIMIZEBOX: DWORD = 0x00010000;
72 | pub const WS_TABSTOP: DWORD = 0x00010000;
73 | pub const WS_GROUP: DWORD = 0x00020000;
74 | pub const WS_MINIMIZEBOX: DWORD = 0x00020000;
75 | pub const WS_THICKFRAME: DWORD = 0x00040000;
76 | pub const WS_SYSMENU: DWORD = 0x00080000;
77 | pub const WS_HSCROLL: DWORD = 0x00100000;
78 | pub const WS_VSCROLL: DWORD = 0x00200000;
79 | pub const WS_DLGFRAME: DWORD = 0x00400000;
80 | pub const WS_BORDER: DWORD = 0x00800000;
81 | pub const WS_CAPTION: DWORD = WS_BORDER | 0x00400000;
82 | pub const WS_MAXIMIZE: DWORD = 0x01000000;
83 | pub const WS_CLIPCHILDREN: DWORD = 0x02000000;
84 | pub const WS_CLIPSIBLINGS: DWORD = 0x04000000;
85 | pub const WS_DISABLED: DWORD = 0x08000000;
86 | pub const WS_VISIBLE: DWORD = 0x10000000;
87 | pub const WS_ICONIC: DWORD = 0x20000000;
88 | pub const WS_MINIMIZE: DWORD = 0x20000000;
89 | pub const WS_CHILD: DWORD = 0x40000000;
90 | pub const WS_CHILDWINDOW: DWORD = 0x40000000;
91 | pub const WS_POPUP: DWORD = @truncate(0x80000000);
92 | pub const WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
93 | pub const WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU);
94 | pub const WS_TILEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
95 |
96 | pub const WS_EX_LEFT: DWORD = 0x00000000;
97 | pub const WS_EX_RIGHTSCROLLBAR: DWORD = 0x00000000;
98 | pub const WS_EX_LTRREADING: DWORD = 0x00000000;
99 | pub const WS_EX_DLGMODALFRAME: DWORD = 0x00000001;
100 | pub const WS_EX_NOPARENTNOTIFY: DWORD = 0x00000004;
101 | pub const WS_EX_TOPMOST: DWORD = 0x00000008;
102 | pub const WS_EX_ACCEPTFILES: DWORD = 0x00000010;
103 | pub const WS_EX_TRANSPARENT: DWORD = 0x00000020;
104 | pub const WS_EX_MDICHILD: DWORD = 0x00000040;
105 | pub const WS_EX_TOOLWINDOW: DWORD = 0x00000080;
106 | pub const WS_EX_WINDOWEDGE: DWORD = 0x00000100;
107 | pub const WS_EX_CLIENTEDGE: DWORD = 0x00000200;
108 | pub const WS_EX_CONTEXTHELP: DWORD = 0x00000400;
109 | pub const WS_EX_RIGHT: DWORD = 0x00001000;
110 | pub const WS_EX_RTLREADING: DWORD = 0x00002000;
111 | pub const WS_EX_LEFTSCROLLBAR: DWORD = 0x00004000;
112 | pub const WS_EX_CONTROLPARENT: DWORD = 0x00010000;
113 | pub const WS_EX_STATICEDGE: DWORD = 0x00020000;
114 | pub const WS_EX_APPWINDOW: DWORD = 0x00040000;
115 | pub const WS_EX_LAYERED: DWORD = 0x00080000;
116 | pub const WS_EX_NOINHERITLAYOUT: DWORD = 0x00100000;
117 | pub const WS_EX_NOREDIRECTIONBITMAP: DWORD = 0x00200000;
118 | pub const WS_EX_LAYOUTRTL: DWORD = 0x00400000;
119 | pub const WS_EX_COMPOSITED: DWORD = 0x02000000;
120 | pub const WS_EX_NOACTIVATE: DWORD = 0x08000000;
121 | pub const WS_EX_OVERLAPPEDWINDOW: DWORD = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
122 | pub const WS_EX_PALETTEWINDOW: DWORD = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
123 |
124 | pub const CS_VREDRAW: UINT = 0x0001;
125 | pub const CS_HREDRAW: UINT = 0x0002;
126 | pub const CS_DBLCLKS: UINT = 0x0008;
127 | pub const CS_OWNDC: UINT = 0x0020;
128 | pub const CS_CLASSDC: UINT = 0x0040;
129 | pub const CS_PARENTDC: UINT = 0x0080;
130 | pub const CS_NOCLOSE: UINT = 0x0200;
131 | pub const CS_SAVEBITS: UINT = 0x0800;
132 | pub const CS_BYTEALIGNCLIENT: UINT = 0x1000;
133 | pub const CS_BYTEALIGNWINDOW: UINT = 0x2000;
134 | pub const CS_GLOBALCLASS: UINT = 0x4000;
135 | pub const CS_IME: UINT = 0x00010000;
136 | pub const CS_DROPSHADOW: UINT = 0x00020000;
137 |
138 | pub inline fn MAKEINTRESOURCE(i: u16) LPCWSTR {
139 | return @ptrFromInt(i);
140 | }
141 |
142 | pub const TD_WARNING_ICON = MAKEINTRESOURCE(@truncate(-1));
143 | pub const TD_ERROR_ICON = MAKEINTRESOURCE(@truncate(-2));
144 | pub const TD_INFORMATION_ICON = MAKEINTRESOURCE(@truncate(-3));
145 | pub const TD_SHIELD_ICON = MAKEINTRESOURCE(@truncate(-4));
146 |
147 | pub const IDC_ARROW = MAKEINTRESOURCE(32512);
148 | pub const IDC_IBEAM = MAKEINTRESOURCE(32513);
149 | pub const IDC_WAIT = MAKEINTRESOURCE(32514);
150 | pub const IDC_CROSS = MAKEINTRESOURCE(32515);
151 | pub const IDC_UPARROW = MAKEINTRESOURCE(32516);
152 | pub const IDC_SIZE = MAKEINTRESOURCE(32640);
153 | pub const IDC_ICON = MAKEINTRESOURCE(32641);
154 | pub const IDC_SIZENWSE = MAKEINTRESOURCE(32642);
155 | pub const IDC_SIZENESW = MAKEINTRESOURCE(32643);
156 | pub const IDC_SIZEWE = MAKEINTRESOURCE(32644);
157 | pub const IDC_SIZENS = MAKEINTRESOURCE(32645);
158 | pub const IDC_SIZEALL = MAKEINTRESOURCE(32646);
159 | pub const IDC_NO = MAKEINTRESOURCE(32648);
160 | pub const IDC_HAND = MAKEINTRESOURCE(32649);
161 | pub const IDC_APPSTARTING = MAKEINTRESOURCE(32650);
162 | pub const IDC_HELP = MAKEINTRESOURCE(32651);
163 | pub const IDC_PIN = MAKEINTRESOURCE(32671);
164 | pub const IDC_PERSON = MAKEINTRESOURCE(32672);
165 |
166 | pub const PM_NOREMOVE: UINT = 0x0000;
167 | pub const PM_REMOVE: UINT = 0x0001;
168 | pub const PM_NOYIELD: UINT = 0x0002;
169 |
170 | pub const WA_INACTIVE: UINT = 0;
171 | pub const WA_ACTIVE: UINT = 1;
172 | pub const WA_CLICKACTIVE: UINT = 2;
173 |
174 | //#region Window message
175 | pub const WM_NULL: UINT = 0x0000;
176 | pub const WM_CREATE: UINT = 0x0001;
177 | pub const WM_DESTROY: UINT = 0x0002;
178 | pub const WM_MOVE: UINT = 0x0003;
179 | pub const WM_SIZE: UINT = 0x0005;
180 | pub const WM_ACTIVATE: UINT = 0x0006;
181 | pub const WM_SETFOCUS: UINT = 0x0007;
182 | pub const WM_KILLFOCUS: UINT = 0x0008;
183 | pub const WM_ENABLE: UINT = 0x000A;
184 | pub const WM_SETREDRAW: UINT = 0x000B;
185 | pub const WM_SETTEXT: UINT = 0x000C;
186 | pub const WM_GETTEXT: UINT = 0x000D;
187 | pub const WM_GETTEXTLENGTH: UINT = 0x000E;
188 | pub const WM_PAINT: UINT = 0x000F;
189 | pub const WM_CLOSE: UINT = 0x0010;
190 | pub const WM_QUERYENDSESSION: UINT = 0x0011;
191 | pub const WM_QUERYOPEN: UINT = 0x0013;
192 | pub const WM_ENDSESSION: UINT = 0x0016;
193 | pub const WM_QUIT: UINT = 0x0012;
194 | pub const WM_ERASEBKGND: UINT = 0x0014;
195 | pub const WM_SYSCOLORCHANGE: UINT = 0x0015;
196 | pub const WM_SHOWWINDOW: UINT = 0x0018;
197 | pub const WM_WININICHANGE: UINT = 0x001A;
198 | pub const WM_SETTINGCHANGE: UINT = WM_WININICHANGE;
199 | pub const WM_DEVMODECHANGE: UINT = 0x001B;
200 | pub const WM_ACTIVATEAPP: UINT = 0x001C;
201 | pub const WM_FONTCHANGE: UINT = 0x001D;
202 | pub const WM_TIMECHANGE: UINT = 0x001E;
203 | pub const WM_CANCELMODE: UINT = 0x001F;
204 | pub const WM_SETCURSOR: UINT = 0x0020;
205 | pub const WM_MOUSEACTIVATE: UINT = 0x0021;
206 | pub const WM_CHILDACTIVATE: UINT = 0x0022;
207 | pub const WM_QUEUESYNC: UINT = 0x0023;
208 | pub const WM_GETMINMAXINFO: UINT = 0x0024;
209 | pub const WM_PAINTICON: UINT = 0x0026;
210 | pub const WM_ICONERASEBKGND: UINT = 0x0027;
211 | pub const WM_NEXTDLGCTL: UINT = 0x0028;
212 | pub const WM_SPOOLERSTATUS: UINT = 0x002A;
213 | pub const WM_DRAWITEM: UINT = 0x002B;
214 | pub const WM_MEASUREITEM: UINT = 0x002C;
215 | pub const WM_DELETEITEM: UINT = 0x002D;
216 | pub const WM_VKEYTOITEM: UINT = 0x002E;
217 | pub const WM_CHARTOITEM: UINT = 0x002F;
218 | pub const WM_SETFONT: UINT = 0x0030;
219 | pub const WM_GETFONT: UINT = 0x0031;
220 | pub const WM_SETHOTKEY: UINT = 0x0032;
221 | pub const WM_GETHOTKEY: UINT = 0x0033;
222 | pub const WM_QUERYDRAGICON: UINT = 0x0037;
223 | pub const WM_COMPAREITEM: UINT = 0x0039;
224 | pub const WM_GETOBJECT: UINT = 0x003D;
225 | pub const WM_COMPACTING: UINT = 0x0041;
226 | pub const WM_COMMNOTIFY: UINT = 0x0044;
227 | pub const WM_WINDOWPOSCHANGING: UINT = 0x0046;
228 | pub const WM_WINDOWPOSCHANGED: UINT = 0x0047;
229 | pub const WM_POWER: UINT = 0x0048;
230 | pub const WM_COPYDATA: UINT = 0x004A;
231 | pub const WM_CANCELJOURNAL: UINT = 0x004B;
232 | pub const WM_NOTIFY: UINT = 0x004E;
233 | pub const WM_INPUTLANGCHANGEREQUEST: UINT = 0x0050;
234 | pub const WM_INPUTLANGCHANGE: UINT = 0x0051;
235 | pub const WM_TCARD: UINT = 0x0052;
236 | pub const WM_HELP: UINT = 0x0053;
237 | pub const WM_USERCHANGED: UINT = 0x0054;
238 | pub const WM_NOTIFYFORMAT: UINT = 0x0055;
239 | pub const WM_CONTEXTMENU: UINT = 0x007B;
240 | pub const WM_STYLECHANGING: UINT = 0x007C;
241 | pub const WM_STYLECHANGED: UINT = 0x007D;
242 | pub const WM_DISPLAYCHANGE: UINT = 0x007E;
243 | pub const WM_GETICON: UINT = 0x007F;
244 | pub const WM_SETICON: UINT = 0x0080;
245 | pub const WM_NCCREATE: UINT = 0x0081;
246 | pub const WM_NCDESTROY: UINT = 0x0082;
247 | pub const WM_NCCALCSIZE: UINT = 0x0083;
248 | pub const WM_NCHITTEST: UINT = 0x0084;
249 | pub const WM_NCPAINT: UINT = 0x0085;
250 | pub const WM_NCACTIVATE: UINT = 0x0086;
251 | pub const WM_GETDLGCODE: UINT = 0x0087;
252 | pub const WM_SYNCPAINT: UINT = 0x0088;
253 | pub const WM_NCMOUSEMOVE: UINT = 0x00A0;
254 | pub const WM_NCLBUTTONDOWN: UINT = 0x00A1;
255 | pub const WM_NCLBUTTONUP: UINT = 0x00A2;
256 | pub const WM_NCLBUTTONDBLCLK: UINT = 0x00A3;
257 | pub const WM_NCRBUTTONDOWN: UINT = 0x00A4;
258 | pub const WM_NCRBUTTONUP: UINT = 0x00A5;
259 | pub const WM_NCRBUTTONDBLCLK: UINT = 0x00A6;
260 | pub const WM_NCMBUTTONDOWN: UINT = 0x00A7;
261 | pub const WM_NCMBUTTONUP: UINT = 0x00A8;
262 | pub const WM_NCMBUTTONDBLCLK: UINT = 0x00A9;
263 | pub const WM_NCXBUTTONDOWN: UINT = 0x00AB;
264 | pub const WM_NCXBUTTONUP: UINT = 0x00AC;
265 | pub const WM_NCXBUTTONDBLCLK: UINT = 0x00AD;
266 | pub const WM_INPUT_DEVICE_CHANGE: UINT = 0x00FE;
267 | pub const WM_INPUT: UINT = 0x00FF;
268 | pub const WM_KEYFIRST: UINT = 0x0100;
269 | pub const WM_KEYDOWN: UINT = 0x0100;
270 | pub const WM_KEYUP: UINT = 0x0101;
271 | pub const WM_CHAR: UINT = 0x0102;
272 | pub const WM_DEADCHAR: UINT = 0x0103;
273 | pub const WM_SYSKEYDOWN: UINT = 0x0104;
274 | pub const WM_SYSKEYUP: UINT = 0x0105;
275 | pub const WM_SYSCHAR: UINT = 0x0106;
276 | pub const WM_SYSDEADCHAR: UINT = 0x0107;
277 | pub const WM_UNICHAR: UINT = 0x0109;
278 | pub const WM_KEYLAST: UINT = 0x0109;
279 | pub const UNICODE_NOCHAR: UINT = 0xFFFF;
280 | pub const WM_IME_STARTCOMPOSITION: UINT = 0x010D;
281 | pub const WM_IME_ENDCOMPOSITION: UINT = 0x010E;
282 | pub const WM_IME_COMPOSITION: UINT = 0x010F;
283 | pub const WM_IME_KEYLAST: UINT = 0x010F;
284 | pub const WM_INITDIALOG: UINT = 0x0110;
285 | pub const WM_COMMAND: UINT = 0x0111;
286 | pub const WM_SYSCOMMAND: UINT = 0x0112;
287 | pub const WM_TIMER: UINT = 0x0113;
288 | pub const WM_HSCROLL: UINT = 0x0114;
289 | pub const WM_VSCROLL: UINT = 0x0115;
290 | pub const WM_INITMENU: UINT = 0x0116;
291 | pub const WM_INITMENUPOPUP: UINT = 0x0117;
292 | pub const WM_GESTURE: UINT = 0x0119;
293 | pub const WM_GESTURENOTIFY: UINT = 0x011A;
294 | pub const WM_MENUSELECT: UINT = 0x011F;
295 | pub const WM_MENUCHAR: UINT = 0x0120;
296 | pub const WM_ENTERIDLE: UINT = 0x0121;
297 | pub const WM_MENURBUTTONUP: UINT = 0x0122;
298 | pub const WM_MENUDRAG: UINT = 0x0123;
299 | pub const WM_MENUGETOBJECT: UINT = 0x0124;
300 | pub const WM_UNINITMENUPOPUP: UINT = 0x0125;
301 | pub const WM_MENUCOMMAND: UINT = 0x0126;
302 | pub const WM_CHANGEUISTATE: UINT = 0x0127;
303 | pub const WM_UPDATEUISTATE: UINT = 0x0128;
304 | pub const WM_QUERYUISTATE: UINT = 0x0129;
305 | pub const WM_CTLCOLORMSGBOX: UINT = 0x0132;
306 | pub const WM_CTLCOLOREDIT: UINT = 0x0133;
307 | pub const WM_CTLCOLORLISTBOX: UINT = 0x0134;
308 | pub const WM_CTLCOLORBTN: UINT = 0x0135;
309 | pub const WM_CTLCOLORDLG: UINT = 0x0136;
310 | pub const WM_CTLCOLORSCROLLBAR: UINT = 0x0137;
311 | pub const WM_CTLCOLORSTATIC: UINT = 0x0138;
312 | pub const MN_GETHMENU: UINT = 0x01E1;
313 | pub const WM_MOUSEMOVE: UINT = 0x0200;
314 | pub const WM_LBUTTONDOWN: UINT = 0x0201;
315 | pub const WM_LBUTTONUP: UINT = 0x0202;
316 | pub const WM_LBUTTONDBLCLK: UINT = 0x0203;
317 | pub const WM_RBUTTONDOWN: UINT = 0x0204;
318 | pub const WM_RBUTTONUP: UINT = 0x0205;
319 | pub const WM_RBUTTONDBLCLK: UINT = 0x0206;
320 | pub const WM_MBUTTONDOWN: UINT = 0x0207;
321 | pub const WM_MBUTTONUP: UINT = 0x0208;
322 | pub const WM_MBUTTONDBLCLK: UINT = 0x0209;
323 | pub const WM_MOUSEWHEEL: UINT = 0x020A;
324 | pub const WM_XBUTTONDOWN: UINT = 0x020B;
325 | pub const WM_XBUTTONUP: UINT = 0x020C;
326 | pub const WM_XBUTTONDBLCLK: UINT = 0x020D;
327 | pub const WM_MOUSEHWHEEL: UINT = 0x020E;
328 | pub const WM_MOUSELAST: UINT = 0x020E;
329 | pub const WM_PARENTNOTIFY: UINT = 0x0210;
330 | pub const WM_ENTERMENULOOP: UINT = 0x0211;
331 | pub const WM_EXITMENULOOP: UINT = 0x0212;
332 | pub const WM_NEXTMENU: UINT = 0x0213;
333 | pub const WM_SIZING: UINT = 0x0214;
334 | pub const WM_CAPTURECHANGED: UINT = 0x0215;
335 | pub const WM_MOVING: UINT = 0x0216;
336 | pub const WM_POWERBROADCAST: UINT = 0x0218;
337 | pub const WM_DEVICECHANGE: UINT = 0x0219;
338 | pub const WM_MDICREATE: UINT = 0x0220;
339 | pub const WM_MDIDESTROY: UINT = 0x0221;
340 | pub const WM_MDIACTIVATE: UINT = 0x0222;
341 | pub const WM_MDIRESTORE: UINT = 0x0223;
342 | pub const WM_MDINEXT: UINT = 0x0224;
343 | pub const WM_MDIMAXIMIZE: UINT = 0x0225;
344 | pub const WM_MDITILE: UINT = 0x0226;
345 | pub const WM_MDICASCADE: UINT = 0x0227;
346 | pub const WM_MDIICONARRANGE: UINT = 0x0228;
347 | pub const WM_MDIGETACTIVE: UINT = 0x0229;
348 | pub const WM_MDISETMENU: UINT = 0x0230;
349 | pub const WM_ENTERSIZEMOVE: UINT = 0x0231;
350 | pub const WM_EXITSIZEMOVE: UINT = 0x0232;
351 | pub const WM_DROPFILES: UINT = 0x0233;
352 | pub const WM_MDIREFRESHMENU: UINT = 0x0234;
353 | pub const WM_POINTERDEVICECHANGE: UINT = 0x238;
354 | pub const WM_POINTERDEVICEINRANGE: UINT = 0x239;
355 | pub const WM_POINTERDEVICEOUTOFRANGE: UINT = 0x23A;
356 | pub const WM_TOUCH: UINT = 0x0240;
357 | pub const WM_NCPOINTERUPDATE: UINT = 0x0241;
358 | pub const WM_NCPOINTERDOWN: UINT = 0x0242;
359 | pub const WM_NCPOINTERUP: UINT = 0x0243;
360 | pub const WM_POINTERUPDATE: UINT = 0x0245;
361 | pub const WM_POINTERDOWN: UINT = 0x0246;
362 | pub const WM_POINTERUP: UINT = 0x0247;
363 | pub const WM_POINTERENTER: UINT = 0x0249;
364 | pub const WM_POINTERLEAVE: UINT = 0x024A;
365 | pub const WM_POINTERACTIVATE: UINT = 0x024B;
366 | pub const WM_POINTERCAPTURECHANGED: UINT = 0x024C;
367 | pub const WM_TOUCHHITTESTING: UINT = 0x024D;
368 | pub const WM_POINTERWHEEL: UINT = 0x024E;
369 | pub const WM_POINTERHWHEEL: UINT = 0x024F;
370 | pub const WM_POINTERROUTEDTO: UINT = 0x0251;
371 | pub const WM_POINTERROUTEDAWAY: UINT = 0x0252;
372 | pub const WM_POINTERROUTEDRELEASED: UINT = 0x0253;
373 | pub const WM_IME_SETCONTEXT: UINT = 0x0281;
374 | pub const WM_IME_NOTIFY: UINT = 0x0282;
375 | pub const WM_IME_CONTROL: UINT = 0x0283;
376 | pub const WM_IME_COMPOSITIONFULL: UINT = 0x0284;
377 | pub const WM_IME_SELECT: UINT = 0x0285;
378 | pub const WM_IME_CHAR: UINT = 0x0286;
379 | pub const WM_IME_REQUEST: UINT = 0x0288;
380 | pub const WM_IME_KEYDOWN: UINT = 0x0290;
381 | pub const WM_IME_KEYUP: UINT = 0x0291;
382 | pub const WM_MOUSEHOVER: UINT = 0x02A1;
383 | pub const WM_MOUSELEAVE: UINT = 0x02A3;
384 | pub const WM_NCMOUSEHOVER: UINT = 0x02A0;
385 | pub const WM_NCMOUSELEAVE: UINT = 0x02A2;
386 | pub const WM_WTSSESSION_CHANGE: UINT = 0x02B1;
387 | pub const WM_TABLET_FIRST: UINT = 0x02c0;
388 | pub const WM_TABLET_LAST: UINT = 0x02df;
389 | pub const WM_DPICHANGED: UINT = 0x02E0;
390 | pub const WM_DPICHANGED_BEFOREPARENT: UINT = 0x02E2;
391 | pub const WM_DPICHANGED_AFTERPARENT: UINT = 0x02E3;
392 | pub const WM_GETDPISCALEDSIZE: UINT = 0x02E4;
393 | pub const WM_CUT: UINT = 0x0300;
394 | pub const WM_COPY: UINT = 0x0301;
395 | pub const WM_PASTE: UINT = 0x0302;
396 | pub const WM_CLEAR: UINT = 0x0303;
397 | pub const WM_UNDO: UINT = 0x0304;
398 | pub const WM_RENDERFORMAT: UINT = 0x0305;
399 | pub const WM_RENDERALLFORMATS: UINT = 0x0306;
400 | pub const WM_DESTROYCLIPBOARD: UINT = 0x0307;
401 | pub const WM_DRAWCLIPBOARD: UINT = 0x0308;
402 | pub const WM_PAINTCLIPBOARD: UINT = 0x0309;
403 | pub const WM_VSCROLLCLIPBOARD: UINT = 0x030A;
404 | pub const WM_SIZECLIPBOARD: UINT = 0x030B;
405 | pub const WM_ASKCBFORMATNAME: UINT = 0x030C;
406 | pub const WM_CHANGECBCHAIN: UINT = 0x030D;
407 | pub const WM_HSCROLLCLIPBOARD: UINT = 0x030E;
408 | pub const WM_QUERYNEWPALETTE: UINT = 0x030F;
409 | pub const WM_PALETTEISCHANGING: UINT = 0x0310;
410 | pub const WM_PALETTECHANGED: UINT = 0x0311;
411 | pub const WM_HOTKEY: UINT = 0x0312;
412 | pub const WM_PRINT: UINT = 0x0317;
413 | pub const WM_PRINTCLIENT: UINT = 0x0318;
414 | pub const WM_APPCOMMAND: UINT = 0x0319;
415 | pub const WM_THEMECHANGED: UINT = 0x031A;
416 | pub const WM_CLIPBOARDUPDATE: UINT = 0x031D;
417 | pub const WM_DWMCOMPOSITIONCHANGED: UINT = 0x031E;
418 | pub const WM_DWMNCRENDERINGCHANGED: UINT = 0x031F;
419 | pub const WM_DWMCOLORIZATIONCOLORCHANGED: UINT = 0x0320;
420 | pub const WM_DWMWINDOWMAXIMIZEDCHANGE: UINT = 0x0321;
421 | pub const WM_DWMSENDICONICTHUMBNAIL: UINT = 0x0323;
422 | pub const WM_DWMSENDICONICLIVEPREVIEWBITMAP: UINT = 0x0326;
423 | pub const WM_GETTITLEBARINFOEX: UINT = 0x033F;
424 | pub const WM_HANDHELDFIRST: UINT = 0x0358;
425 | pub const WM_HANDHELDLAST: UINT = 0x035F;
426 | pub const WM_AFXFIRST: UINT = 0x0360;
427 | pub const WM_AFXLAST: UINT = 0x037F;
428 | pub const WM_PENWINFIRST: UINT = 0x0380;
429 | pub const WM_PENWINLAST: UINT = 0x038F;
430 | pub const WM_APP: UINT = 0x8000;
431 | pub const WM_USER: UINT = 0x0400;
432 | //#endregion
433 |
434 | pub const TDN_CREATED: UINT = 0;
435 | pub const TDN_NAVIGATED: UINT = 1;
436 | pub const TDN_BUTTON_CLICKED: UINT = 2;
437 | pub const TDN_HYPERLINK_CLICKED: UINT = 3;
438 | pub const TDN_TIMER: UINT = 4;
439 | pub const TDN_DESTROYED: UINT = 5;
440 | pub const TDN_RADIO_BUTTON_CLICKED: UINT = 6;
441 | pub const TDN_DIALOG_CONSTRUCTED: UINT = 7;
442 | pub const TDN_VERIFICATION_CLICKED: UINT = 8;
443 | pub const TDN_HELP: UINT = 9;
444 | pub const TDN_EXPANDO_BUTTON_CLICKED: UINT = 10;
445 |
446 | pub const IDOK: u32 = 1;
447 | pub const IDCANCEL: u32 = 2;
448 | pub const IDABORT: u32 = 3;
449 | pub const IDRETRY: u32 = 4;
450 | pub const IDIGNORE: u32 = 5;
451 | pub const IDYES: u32 = 6;
452 | pub const IDNO: u32 = 7;
453 | pub const IDCLOSE: u32 = 8;
454 | pub const IDHELP: u32 = 9;
455 | pub const IDTRYAGAIN: u32 = 10;
456 | pub const IDCONTINUE: u32 = 11;
457 | pub const IDBUTTONINDEX0: u32 = 100;
458 | pub const IDTIMEOUT: u32 = 32000;
459 |
460 | pub const PFD_DRAW_TO_WINDOW: DWORD = 0x00000004;
461 | pub const PFD_DRAW_TO_BITMAP: DWORD = 0x00000008;
462 | pub const PFD_SUPPORT_GDI: DWORD = 0x00000010;
463 | pub const PFD_SUPPORT_OPENGL: DWORD = 0x00000020;
464 | pub const PFD_GENERIC_ACCELERATED: DWORD = 0x00001000;
465 | pub const PFD_GENERIC_FORMAT: DWORD = 0x00000040;
466 | pub const PFD_NEED_PALETTE: DWORD = 0x00000080;
467 | pub const PFD_NEED_SYSTEM_PALETTE: DWORD = 0x00000100;
468 | pub const PFD_DOUBLEBUFFER: DWORD = 0x00000001;
469 | pub const PFD_STEREO: DWORD = 0x00000002;
470 | pub const PFD_SWAP_LAYER_BUFFERS: DWORD = 0x00000800;
471 | pub const PFD_DEPTH_DONTCARE: DWORD = 0x20000000;
472 | pub const PFD_DOUBLEBUFFER_DONTCARE: DWORD = 0x40000000;
473 | pub const PFD_STEREO_DONTCARE: DWORD = 0x80000000;
474 | pub const PFD_SWAP_COPY: DWORD = 0x00000400;
475 | pub const PFD_SWAP_EXCHANGE: DWORD = 0x00000200;
476 | pub const PFD_TYPE_RGBA: BYTE = 0;
477 | pub const PFD_TYPE_COLORINDEX: BYTE = 1;
478 |
479 | pub const SW_HIDE: i32 = 0;
480 | pub const SW_SHOWNORMAL: i32 = 1;
481 | pub const SW_NORMAL: i32 = 1;
482 | pub const SW_SHOWMINIMIZED: i32 = 2;
483 | pub const SW_SHOWMAXIMIZED: i32 = 3;
484 | pub const SW_MAXIMIZE: i32 = 3;
485 | pub const SW_SHOWNOACTIVATE: i32 = 4;
486 | pub const SW_SHOW: i32 = 5;
487 | pub const SW_MINIMIZE: i32 = 6;
488 | pub const SW_SHOWMINNOACTIVE: i32 = 7;
489 | pub const SW_SHOWNA: i32 = 8;
490 | pub const SW_RESTORE: i32 = 9;
491 | pub const SW_SHOWDEFAULT: i32 = 0;
492 | pub const SW_FORCEMINIMIZE: i32 = 1;
493 |
494 | pub const WMSZ_BOTTOM: WPARAM = 6;
495 | pub const WMSZ_BOTTOMLEFT: WPARAM = 7;
496 | pub const WMSZ_BOTTOMRIGHT: WPARAM = 8;
497 | pub const WMSZ_LEFT: WPARAM = 1;
498 | pub const WMSZ_RIGHT: WPARAM = 2;
499 | pub const WMSZ_TOP: WPARAM = 3;
500 | pub const WMSZ_TOPLEFT: WPARAM = 4;
501 | pub const WMSZ_TOPRIGHT: WPARAM = 5;
502 |
503 | pub const HTBORDER: UINT = 18;
504 | pub const HTBOTTOM: UINT = 15;
505 | pub const HTBOTTOMLEFT: UINT = 16;
506 | pub const HTBOTTOMRIGHT: UINT = 17;
507 | pub const HTCAPTION: UINT = 2;
508 | pub const HTCLIENT: UINT = 1;
509 | pub const HTCLOSE: UINT = 20;
510 | pub const HTERROR: UINT = -2;
511 | pub const HTGROWBOX: UINT = 4;
512 | pub const HTHELP: UINT = 21;
513 | pub const HTHSCROLL: UINT = 6;
514 | pub const HTLEFT: UINT = 10;
515 | pub const HTMENU: UINT = 5;
516 | pub const HTMAXBUTTON: UINT = 9;
517 | pub const HTMINBUTTON: UINT = 8;
518 | pub const HTNOWHERE: UINT = 0;
519 | pub const HTREDUCE: UINT = 8;
520 | pub const HTRIGHT: UINT = 11;
521 | pub const HTSIZE: UINT = 4;
522 | pub const HTSYSMENU: UINT = 3;
523 | pub const HTTOP: UINT = 12;
524 | pub const HTTOPLEFT: UINT = 13;
525 | pub const HTTOPRIGHT: UINT = 14;
526 | pub const HTTRANSPARENT: UINT = 0xFFFFFFFF;
527 | pub const HTVSCROLL: UINT = 7;
528 | pub const HTZOOM: UINT = 9;
529 |
530 | pub const DBT_NO_DISK_SPACE: DWORD = 0x0047;
531 | pub const DBT_LOW_DISK_SPACE: DWORD = 0x0048;
532 | pub const DBT_CONFIGMGPRIVATE: DWORD = 0x7FFF;
533 | pub const DBT_DEVICEARRIVAL: DWORD = 0x8000;
534 | pub const DBT_DEVICEQUERYREMOVE: DWORD = 0x8001;
535 | pub const DBT_DEVICEQUERYREMOVEFAILED: DWORD = 0x8002;
536 | pub const DBT_DEVICEREMOVEPENDING: DWORD = 0x8003;
537 | pub const DBT_DEVICEREMOVECOMPLETE: DWORD = 0x8004;
538 | pub const DBT_DEVICETYPESPECIFIC: DWORD = 0x8005;
539 | pub const DBT_CUSTOMEVENT: DWORD = 0x8006;
540 | pub const DBT_DEVTYP_OEM: DWORD = 0x00000000;
541 | pub const DBT_DEVTYP_DEVNODE: DWORD = 0x00000001;
542 | pub const DBT_DEVTYP_VOLUME: DWORD = 0x00000002;
543 | pub const DBT_DEVTYP_PORT: DWORD = 0x00000003;
544 | pub const DBT_DEVTYP_NET: DWORD = 0x00000004;
545 | pub const DBT_DEVTYP_DEVICEINTERFACE: DWORD = 0x00000005;
546 | pub const DBT_DEVTYP_HANDLE: DWORD = 0x00000006;
547 |
548 | pub const DEVICE_NOTIFY_WINDOW_HANDLE: DWORD = 0x00000000;
549 | pub const DEVICE_NOTIFY_SERVICE_HANDLE: DWORD = 0x00000001;
550 | pub const DEVICE_NOTIFY_ALL_INTERFACE_CLASSES: DWORD = 0x00000004;
551 |
552 | pub const WGL_CONTEXT_MAJOR_VERSION_ARB: i32 = 0x2091;
553 | pub const WGL_CONTEXT_MINOR_VERSION_ARB: i32 = 0x2092;
554 | pub const WGL_CONTEXT_LAYER_PLANE_ARB: i32 = 0x2093;
555 | pub const WGL_CONTEXT_FLAGS_ARB: i32 = 0x2094;
556 | pub const WGL_CONTEXT_PROFILE_MASK_ARB: i32 = 0x9126;
557 | pub const WGL_CONTEXT_DEBUG_BIT_ARB: u32 = 0x0001;
558 | pub const WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB: u32 = 0x0002;
559 | pub const WGL_CONTEXT_CORE_PROFILE_BIT_ARB: u32 = 0x00000001;
560 | pub const WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: u32 = 0x00000002;
561 | pub const ERROR_INVALID_VERSION_ARB: DWORD = 0x2095;
562 | pub const ERROR_INVALID_PROFILE_ARB: DWORD = 0x2096;
563 | pub const ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB: DWORD = 0x2054;
564 |
565 | pub const MAPVK_VK_TO_VSC: UINT = 0;
566 | pub const MAPVK_VSC_TO_VK: UINT = 1;
567 | pub const MAPVK_VK_TO_CHAR: UINT = 2;
568 | pub const MAPVK_VSC_TO_VK_EX: UINT = 3;
569 |
570 | pub const WGL_NUMBER_PIXEL_FORMATS_ARB: i32 = 0x2000;
571 | pub const WGL_DRAW_TO_WINDOW_ARB: i32 = 0x2001;
572 | pub const WGL_DRAW_TO_BITMAP_ARB: i32 = 0x2002;
573 | pub const WGL_ACCELERATION_ARB: i32 = 0x2003;
574 | pub const WGL_NEED_PALETTE_ARB: i32 = 0x2004;
575 | pub const WGL_NEED_SYSTEM_PALETTE_ARB: i32 = 0x2005;
576 | pub const WGL_SWAP_LAYER_BUFFERS_ARB: i32 = 0x2006;
577 | pub const WGL_SWAP_METHOD_ARB: i32 = 0x2007;
578 | pub const WGL_NUMBER_OVERLAYS_ARB: i32 = 0x2008;
579 | pub const WGL_NUMBER_UNDERLAYS_ARB: i32 = 0x2009;
580 | pub const WGL_TRANSPARENT_ARB: i32 = 0x200A;
581 | pub const WGL_TRANSPARENT_RED_VALUE_ARB: i32 = 0x2037;
582 | pub const WGL_TRANSPARENT_GREEN_VALUE_ARB: i32 = 0x2038;
583 | pub const WGL_TRANSPARENT_BLUE_VALUE_ARB: i32 = 0x2039;
584 | pub const WGL_TRANSPARENT_ALPHA_VALUE_ARB: i32 = 0x203A;
585 | pub const WGL_TRANSPARENT_INDEX_VALUE_ARB: i32 = 0x203B;
586 | pub const WGL_SHARE_DEPTH_ARB: i32 = 0x200C;
587 | pub const WGL_SHARE_STENCIL_ARB: i32 = 0x200D;
588 | pub const WGL_SHARE_ACCUM_ARB: i32 = 0x200E;
589 | pub const WGL_SUPPORT_GDI_ARB: i32 = 0x200F;
590 | pub const WGL_SUPPORT_OPENGL_ARB: i32 = 0x2010;
591 | pub const WGL_DOUBLE_BUFFER_ARB: i32 = 0x2011;
592 | pub const WGL_STEREO_ARB: i32 = 0x2012;
593 | pub const WGL_PIXEL_TYPE_ARB: i32 = 0x2013;
594 | pub const WGL_COLOR_BITS_ARB: i32 = 0x2014;
595 | pub const WGL_RED_BITS_ARB: i32 = 0x2015;
596 | pub const WGL_RED_SHIFT_ARB: i32 = 0x2016;
597 | pub const WGL_GREEN_BITS_ARB: i32 = 0x2017;
598 | pub const WGL_GREEN_SHIFT_ARB: i32 = 0x2018;
599 | pub const WGL_BLUE_BITS_ARB: i32 = 0x2019;
600 | pub const WGL_BLUE_SHIFT_ARB: i32 = 0x201A;
601 | pub const WGL_ALPHA_BITS_ARB: i32 = 0x201B;
602 | pub const WGL_ALPHA_SHIFT_ARB: i32 = 0x201C;
603 | pub const WGL_ACCUM_BITS_ARB: i32 = 0x201D;
604 | pub const WGL_ACCUM_RED_BITS_ARB: i32 = 0x201E;
605 | pub const WGL_ACCUM_GREEN_BITS_ARB: i32 = 0x201F;
606 | pub const WGL_ACCUM_BLUE_BITS_ARB: i32 = 0x2020;
607 | pub const WGL_ACCUM_ALPHA_BITS_ARB: i32 = 0x2021;
608 | pub const WGL_DEPTH_BITS_ARB: i32 = 0x2022;
609 | pub const WGL_STENCIL_BITS_ARB: i32 = 0x2023;
610 | pub const WGL_AUX_BUFFERS_ARB: i32 = 0x2024;
611 | pub const WGL_NO_ACCELERATION_ARB: i32 = 0x2025;
612 | pub const WGL_GENERIC_ACCELERATION_ARB: i32 = 0x2026;
613 | pub const WGL_FULL_ACCELERATION_ARB: i32 = 0x2027;
614 | pub const WGL_SWAP_EXCHANGE_ARB: i32 = 0x2028;
615 | pub const WGL_SWAP_COPY_ARB: i32 = 0x2029;
616 | pub const WGL_SWAP_UNDEFINED_ARB: i32 = 0x202A;
617 | pub const WGL_TYPE_RGBA_ARB: i32 = 0x202B;
618 | pub const WGL_TYPE_COLORINDEX_ARB: i32 = 0x202C;
619 | pub const WGL_SAMPLE_BUFFERS_ARB: i32 = 0x2041;
620 | pub const WGL_SAMPLES_ARB: i32 = 0x2042;
621 |
622 | pub const CP_USASCII: UINT = 1252;
623 | pub const CP_UNICODE: UINT = 1200;
624 | pub const CP_JAUTODETECT: UINT = 50932;
625 | pub const CP_KAUTODETECT: UINT = 50949;
626 | pub const CP_ISO2022JPESC: UINT = 50221;
627 | pub const CP_ISO2022JPSIO: UINT = 50222;
628 | pub const CP_UTF8: UINT = 65001;
629 |
630 | //#region Virtual Keys
631 | pub const VK_LBUTTON: UINT = 0x01;
632 | pub const VK_RBUTTON: UINT = 0x02;
633 | pub const VK_CANCEL: UINT = 0x03;
634 | pub const VK_MBUTTON: UINT = 0x04;
635 | pub const VK_XBUTTON1: UINT = 0x05;
636 | pub const VK_XBUTTON2: UINT = 0x06;
637 | pub const VK_BACK: UINT = 0x08;
638 | pub const VK_TAB: UINT = 0x09;
639 | pub const VK_CLEAR: UINT = 0x0C;
640 | pub const VK_RETURN: UINT = 0x0D;
641 | pub const VK_SHIFT: UINT = 0x10;
642 | pub const VK_CONTROL: UINT = 0x11;
643 | pub const VK_MENU: UINT = 0x12;
644 | pub const VK_PAUSE: UINT = 0x13;
645 | pub const VK_CAPITAL: UINT = 0x14;
646 | pub const VK_KANA: UINT = 0x15;
647 | pub const VK_HANGEUL: UINT = 0x15;
648 | pub const VK_HANGUL: UINT = 0x15;
649 | pub const VK_IME_ON: UINT = 0x16;
650 | pub const VK_JUNJA: UINT = 0x17;
651 | pub const VK_FINAL: UINT = 0x18;
652 | pub const VK_HANJA: UINT = 0x19;
653 | pub const VK_KANJI: UINT = 0x19;
654 | pub const VK_IME_OFF: UINT = 0x1A;
655 | pub const VK_ESCAPE: UINT = 0x1B;
656 | pub const VK_CONVERT: UINT = 0x1C;
657 | pub const VK_NONCONVERT: UINT = 0x1D;
658 | pub const VK_ACCEPT: UINT = 0x1E;
659 | pub const VK_MODECHANGE: UINT = 0x1F;
660 | pub const VK_SPACE: UINT = 0x20;
661 | pub const VK_PRIOR: UINT = 0x21;
662 | pub const VK_NEXT: UINT = 0x22;
663 | pub const VK_END: UINT = 0x23;
664 | pub const VK_HOME: UINT = 0x24;
665 | pub const VK_LEFT: UINT = 0x25;
666 | pub const VK_UP: UINT = 0x26;
667 | pub const VK_RIGHT: UINT = 0x27;
668 | pub const VK_DOWN: UINT = 0x28;
669 | pub const VK_SELECT: UINT = 0x29;
670 | pub const VK_PRINT: UINT = 0x2A;
671 | pub const VK_EXECUTE: UINT = 0x2B;
672 | pub const VK_SNAPSHOT: UINT = 0x2C;
673 | pub const VK_INSERT: UINT = 0x2D;
674 | pub const VK_DELETE: UINT = 0x2E;
675 | pub const VK_HELP: UINT = 0x2F;
676 |
677 | pub const VK_LWIN: UINT = 0x5B;
678 | pub const VK_RWIN: UINT = 0x5C;
679 | pub const VK_APPS: UINT = 0x5D;
680 | pub const VK_SLEEP: UINT = 0x5F;
681 | pub const VK_NUMPAD0: UINT = 0x60;
682 | pub const VK_NUMPAD1: UINT = 0x61;
683 | pub const VK_NUMPAD2: UINT = 0x62;
684 | pub const VK_NUMPAD3: UINT = 0x63;
685 | pub const VK_NUMPAD4: UINT = 0x64;
686 | pub const VK_NUMPAD5: UINT = 0x65;
687 | pub const VK_NUMPAD6: UINT = 0x66;
688 | pub const VK_NUMPAD7: UINT = 0x67;
689 | pub const VK_NUMPAD8: UINT = 0x68;
690 | pub const VK_NUMPAD9: UINT = 0x69;
691 | pub const VK_MULTIPLY: UINT = 0x6A;
692 | pub const VK_ADD: UINT = 0x6B;
693 | pub const VK_SEPARATOR: UINT = 0x6C;
694 | pub const VK_SUBTRACT: UINT = 0x6D;
695 | pub const VK_DECIMAL: UINT = 0x6E;
696 | pub const VK_DIVIDE: UINT = 0x6F;
697 | pub const VK_F1: UINT = 0x70;
698 | pub const VK_F2: UINT = 0x71;
699 | pub const VK_F3: UINT = 0x72;
700 | pub const VK_F4: UINT = 0x73;
701 | pub const VK_F5: UINT = 0x74;
702 | pub const VK_F6: UINT = 0x75;
703 | pub const VK_F7: UINT = 0x76;
704 | pub const VK_F8: UINT = 0x77;
705 | pub const VK_F9: UINT = 0x78;
706 | pub const VK_F10: UINT = 0x79;
707 | pub const VK_F11: UINT = 0x7A;
708 | pub const VK_F12: UINT = 0x7B;
709 | pub const VK_F13: UINT = 0x7C;
710 | pub const VK_F14: UINT = 0x7D;
711 | pub const VK_F15: UINT = 0x7E;
712 | pub const VK_F16: UINT = 0x7F;
713 | pub const VK_F17: UINT = 0x80;
714 | pub const VK_F18: UINT = 0x81;
715 | pub const VK_F19: UINT = 0x82;
716 | pub const VK_F20: UINT = 0x83;
717 | pub const VK_F21: UINT = 0x84;
718 | pub const VK_F22: UINT = 0x85;
719 | pub const VK_F23: UINT = 0x86;
720 | pub const VK_F24: UINT = 0x87;
721 | pub const VK_NUMLOCK: UINT = 0x90;
722 | pub const VK_SCROLL: UINT = 0x91;
723 | pub const VK_OEM_NEC_EQUAL: UINT = 0x92;
724 | pub const VK_OEM_FJ_JISHO: UINT = 0x92;
725 | pub const VK_OEM_FJ_MASSHOU: UINT = 0x93;
726 | pub const VK_OEM_FJ_TOUROKU: UINT = 0x94;
727 | pub const VK_OEM_FJ_LOYA: UINT = 0x95;
728 | pub const VK_OEM_FJ_ROYA: UINT = 0x96;
729 | pub const VK_LSHIFT: UINT = 0xA0;
730 | pub const VK_RSHIFT: UINT = 0xA1;
731 | pub const VK_LCONTROL: UINT = 0xA2;
732 | pub const VK_RCONTROL: UINT = 0xA3;
733 | pub const VK_LMENU: UINT = 0xA4;
734 | pub const VK_RMENU: UINT = 0xA5;
735 | pub const VK_BROWSER_BACK: UINT = 0xA6;
736 | pub const VK_BROWSER_FORWARD: UINT = 0xA7;
737 | pub const VK_BROWSER_REFRESH: UINT = 0xA8;
738 | pub const VK_BROWSER_STOP: UINT = 0xA9;
739 | pub const VK_BROWSER_SEARCH: UINT = 0xAA;
740 | pub const VK_BROWSER_FAVORITES: UINT = 0xAB;
741 | pub const VK_BROWSER_HOME: UINT = 0xAC;
742 | pub const VK_VOLUME_MUTE: UINT = 0xAD;
743 | pub const VK_VOLUME_DOWN: UINT = 0xAE;
744 | pub const VK_VOLUME_UP: UINT = 0xAF;
745 | pub const VK_MEDIA_NEXT_TRACK: UINT = 0xB0;
746 | pub const VK_MEDIA_PREV_TRACK: UINT = 0xB1;
747 | pub const VK_MEDIA_STOP: UINT = 0xB2;
748 | pub const VK_MEDIA_PLAY_PAUSE: UINT = 0xB3;
749 | pub const VK_LAUNCH_MAIL: UINT = 0xB4;
750 | pub const VK_LAUNCH_MEDIA_SELECT: UINT = 0xB5;
751 | pub const VK_LAUNCH_APP1: UINT = 0xB6;
752 | pub const VK_LAUNCH_APP2: UINT = 0xB7;
753 | pub const VK_OEM_1: UINT = 0xBA;
754 | pub const VK_OEM_PLUS: UINT = 0xBB;
755 | pub const VK_OEM_COMMA: UINT = 0xBC;
756 | pub const VK_OEM_MINUS: UINT = 0xBD;
757 | pub const VK_OEM_PERIOD: UINT = 0xBE;
758 | pub const VK_OEM_2: UINT = 0xBF;
759 | pub const VK_OEM_3: UINT = 0xC0;
760 | pub const VK_OEM_4: UINT = 0xDB;
761 | pub const VK_OEM_5: UINT = 0xDC;
762 | pub const VK_OEM_6: UINT = 0xDD;
763 | pub const VK_OEM_7: UINT = 0xDE;
764 | pub const VK_OEM_8: UINT = 0xDF;
765 | pub const VK_OEM_AX: UINT = 0xE1;
766 | pub const VK_OEM_102: UINT = 0xE2;
767 | pub const VK_ICO_HELP: UINT = 0xE3;
768 | pub const VK_ICO_00: UINT = 0xE4;
769 | pub const VK_PROCESSKEY: UINT = 0xE5;
770 | pub const VK_ICO_CLEAR: UINT = 0xE6;
771 | pub const VK_PACKET: UINT = 0xE7;
772 | pub const VK_OEM_RESET: UINT = 0xE9;
773 | pub const VK_OEM_JUMP: UINT = 0xEA;
774 | pub const VK_OEM_PA1: UINT = 0xEB;
775 | pub const VK_OEM_PA2: UINT = 0xEC;
776 | pub const VK_OEM_PA3: UINT = 0xED;
777 | pub const VK_OEM_WSCTRL: UINT = 0xEE;
778 | pub const VK_OEM_CUSEL: UINT = 0xEF;
779 | pub const VK_OEM_ATTN: UINT = 0xF0;
780 | pub const VK_OEM_FINISH: UINT = 0xF1;
781 | pub const VK_OEM_COPY: UINT = 0xF2;
782 | pub const VK_OEM_AUTO: UINT = 0xF3;
783 | pub const VK_OEM_ENLW: UINT = 0xF4;
784 | pub const VK_OEM_BACKTAB: UINT = 0xF5;
785 | pub const VK_ATTN: UINT = 0xF6;
786 | pub const VK_CRSEL: UINT = 0xF7;
787 | pub const VK_EXSEL: UINT = 0xF8;
788 | pub const VK_EREOF: UINT = 0xF9;
789 | pub const VK_PLAY: UINT = 0xFA;
790 | pub const VK_ZOOM: UINT = 0xFB;
791 | pub const VK_NONAME: UINT = 0xFC;
792 | pub const VK_PA1: UINT = 0xFD;
793 | pub const VK_OEM_CLEAR: UINT = 0xFE;
794 | //#endregion
795 |
796 | //#region System metrics
797 | pub const SM_ARRANGE: i32 = 56;
798 | pub const SM_CLEANBOOT: i32 = 67;
799 | pub const SM_CMONITORS: i32 = 80;
800 | pub const SM_CMOUSEBUTTONS: i32 = 43;
801 | pub const SM_CONVERTIBLESLATEMODE: i32 = 0x2003;
802 | pub const SM_CXBORDER: i32 = 5;
803 | pub const SM_CXCURSOR: i32 = 13;
804 | pub const SM_CXDLGFRAME: i32 = 7;
805 | pub const SM_CXDOUBLECLK: i32 = 36;
806 | pub const SM_CXDRAG: i32 = 68;
807 | pub const SM_CXEDGE: i32 = 45;
808 | pub const SM_CXFIXEDFRAME: i32 = 7;
809 | pub const SM_CXFOCUSBORDER: i32 = 83;
810 | pub const SM_CXFRAME: i32 = 32;
811 | pub const SM_CXFULLSCREEN: i32 = 16;
812 | pub const SM_CXHSCROLL: i32 = 21;
813 | pub const SM_CXHTHUMB: i32 = 10;
814 | pub const SM_CXICON: i32 = 11;
815 | pub const SM_CXICONSPACING: i32 = 38;
816 | pub const SM_CXMAXIMIZED: i32 = 61;
817 | pub const SM_CXMAXTRACK: i32 = 59;
818 | pub const SM_CXMENUCHECK: i32 = 71;
819 | pub const SM_CXMENUSIZE: i32 = 54;
820 | pub const SM_CXMIN: i32 = 28;
821 | pub const SM_CXMINIMIZED: i32 = 57;
822 | pub const SM_CXMINSPACING: i32 = 47;
823 | pub const SM_CXMINTRACK: i32 = 34;
824 | pub const SM_CXPADDEDBORDER: i32 = 92;
825 | pub const SM_CXSCREEN: i32 = 0;
826 | pub const SM_CXSIZE: i32 = 30;
827 | pub const SM_CXSIZEFRAME: i32 = 32;
828 | pub const SM_CXSMICON: i32 = 49;
829 | pub const SM_CXSMSIZE: i32 = 52;
830 | pub const SM_CXVIRTUALSCREEN: i32 = 78;
831 | pub const SM_CXVSCROLL: i32 = 2;
832 | pub const SM_CYBORDER: i32 = 6;
833 | pub const SM_CYCAPTION: i32 = 4;
834 | pub const SM_CYCURSOR: i32 = 14;
835 | pub const SM_CYDLGFRAME: i32 = 8;
836 | pub const SM_CYDOUBLECLK: i32 = 37;
837 | pub const SM_CYDRAG: i32 = 69;
838 | pub const SM_CYEDGE: i32 = 46;
839 | pub const SM_CYFIXEDFRAME: i32 = 8;
840 | pub const SM_CYFOCUSBORDER: i32 = 84;
841 | pub const SM_CYFRAME: i32 = 33;
842 | pub const SM_CYFULLSCREEN: i32 = 17;
843 | pub const SM_CYHSCROLL: i32 = 3;
844 | pub const SM_CYICON: i32 = 12;
845 | pub const SM_CYICONSPACING: i32 = 39;
846 | pub const SM_CYKANJIWINDOW: i32 = 18;
847 | pub const SM_CYMAXIMIZED: i32 = 62;
848 | pub const SM_CYMAXTRACK: i32 = 60;
849 | pub const SM_CYMENU: i32 = 15;
850 | pub const SM_CYMENUCHECK: i32 = 72;
851 | pub const SM_CYMENUSIZE: i32 = 55;
852 | pub const SM_CYMIN: i32 = 29;
853 | pub const SM_CYMINIMIZED: i32 = 58;
854 | pub const SM_CYMINSPACING: i32 = 48;
855 | pub const SM_CYMINTRACK: i32 = 35;
856 | pub const SM_CYSCREEN: i32 = 1;
857 | pub const SM_CYSIZE: i32 = 31;
858 | pub const SM_CYSIZEFRAME: i32 = 33;
859 | pub const SM_CYSMCAPTION: i32 = 51;
860 | pub const SM_CYSMICON: i32 = 50;
861 | pub const SM_CYSMSIZE: i32 = 53;
862 | pub const SM_CYVIRTUALSCREEN: i32 = 79;
863 | pub const SM_CYVSCROLL: i32 = 20;
864 | pub const SM_CYVTHUMB: i32 = 9;
865 | pub const SM_DBCSENABLED: i32 = 42;
866 | pub const SM_DEBUG: i32 = 22;
867 | pub const SM_DIGITIZER: i32 = 94;
868 | pub const SM_IMMENABLED: i32 = 82;
869 | pub const SM_MAXIMUMTOUCHES: i32 = 95;
870 | pub const SM_MEDIACENTER: i32 = 87;
871 | pub const SM_MENUDROPALIGNMENT: i32 = 40;
872 | pub const SM_MIDEASTENABLED: i32 = 74;
873 | pub const SM_MOUSEPRESENT: i32 = 19;
874 | pub const SM_MOUSEHORIZONTALWHEELPRESENT: i32 = 91;
875 | pub const SM_MOUSEWHEELPRESENT: i32 = 75;
876 | pub const SM_NETWORK: i32 = 63;
877 | pub const SM_PENWINDOWS: i32 = 41;
878 | pub const SM_REMOTECONTROL: i32 = 0x2001;
879 | pub const SM_REMOTESESSION: i32 = 0x1000;
880 | pub const SM_SAMEDISPLAYFORMAT: i32 = 81;
881 | pub const SM_SECURE: i32 = 44;
882 | pub const SM_SERVERR2: i32 = 89;
883 | pub const SM_SHOWSOUNDS: i32 = 70;
884 | pub const SM_SHUTTINGDOWN: i32 = 0x2000;
885 | pub const SM_SLOWMACHINE: i32 = 73;
886 | pub const SM_STARTER: i32 = 88;
887 | pub const SM_SWAPBUTTON: i32 = 23;
888 | pub const SM_SYSTEMDOCKED: i32 = 0x2004;
889 | pub const SM_TABLETPC: i32 = 86;
890 | pub const SM_XVIRTUALSCREEN: i32 = 76;
891 | pub const SM_YVIRTUALSCREEN: i32 = 77;
892 | //#endregion
893 |
894 | pub const WNDCLASSEXW = extern struct {
895 | cbSize: UINT = @sizeOf(WNDCLASSEXW),
896 | style: UINT,
897 | lpfnWndProc: WNDPROC,
898 | cbClsExtra: i32 = 0,
899 | cbWndExtra: i32 = 0,
900 | hInstance: ?HINSTANCE = null,
901 | hIcon: ?HICON = null,
902 | hCursor: ?HCURSOR = null,
903 | hbrBackground: ?HBRUSH = null,
904 | lpszMenuName: ?LPCWSTR = null,
905 | lpszClassName: LPCWSTR,
906 | hIconSm: ?HICON = null,
907 | };
908 | pub const POINT = extern struct {
909 | x: LONG = 0,
910 | y: LONG = 0,
911 | };
912 | pub const RECT = extern struct {
913 | left: LONG = 0,
914 | top: LONG = 0,
915 | right: LONG = 0,
916 | bottom: LONG = 0,
917 | };
918 | pub const MSG = extern struct {
919 | hwnd: ?HWND,
920 | message: UINT,
921 | wParam: WPARAM,
922 | lParam: LPARAM,
923 | time: DWORD,
924 | pt: POINT,
925 | };
926 | pub const TASKDIALOGCONFIG = extern struct {
927 | cbSize: UINT = @sizeOf(TASKDIALOGCONFIG),
928 | hwndParent: ?HWND,
929 | hInstance: ?HINSTANCE,
930 | dwFlags: TASKDIALOG_FLAGS = .{},
931 | dwCommonButtons: TASKDIALOG_COMMON_BUTTON_FLAGS = .{},
932 | pszWindowTitle: LPCWSTR,
933 | DUMMYUNIONNAME: extern union {
934 | hMainIcon: ?HICON,
935 | pszMainIcon: ?LPCWSTR,
936 | } = .{ .hMainIcon = null },
937 | pszMainInstruction: ?LPCWSTR = null,
938 | pszContent: LPCWSTR,
939 | cButtons: UINT,
940 | pButtons: [*]const TASKDIALOG_BUTTON,
941 | nDefaultButton: u32 = 0,
942 | cRadioButtons: UINT = 0,
943 | pRadioButtons: ?[*]const TASKDIALOG_BUTTON = null,
944 | nDefaultRadioButton: u32 = 0,
945 | pszVerificationText: ?LPCWSTR = null,
946 | pszExpandedInformation: ?LPCWSTR = null,
947 | pszExpandedControlText: ?LPCWSTR = null,
948 | pszCollapsedControlText: ?LPCWSTR = null,
949 | DUMMYUNIONNAME2: extern union {
950 | hFooterIcon: ?HICON,
951 | pszFooterIcon: ?LPCWSTR,
952 | } = .{ .hFooterIcon = null },
953 | pszFooter: ?LPCWSTR = null,
954 | pfCallback: ?PFTASKDIALOGCALLBACK = null,
955 | lpCallbackData: LONG_PTR = 0,
956 | cxWidth: UINT = 0,
957 | };
958 | pub const TASKDIALOG_FLAGS = packed struct {
959 | ENABLE_HYPERLINKS: bool = false,
960 | USE_HICON_MAIN: bool = false,
961 | USE_HICON_FOOTER: bool = false,
962 | ALLOW_DIALOG_CANCELLATION: bool = false,
963 | USE_COMMAND_LINKS: bool = false,
964 | USE_COMMAND_LINKS_NO_ICON: bool = false,
965 | EXPAND_FOOTER_AREA: bool = false,
966 | EXPANDED_BY_DEFAULT: bool = false,
967 | VERIFICATION_FLAG_CHECKED: bool = false,
968 | SHOW_PROGRESS_BAR: bool = false,
969 | SHOW_MARQUEE_PROGRESS_BAR: bool = false,
970 | CALLBACK_TIMER: bool = false,
971 | POSITION_RELATIVE_TO_WINDOW: bool = false,
972 | RTL_LAYOUT: bool = false,
973 | NO_DEFAULT_RADIO_BUTTON: bool = false,
974 | CAN_BE_MINIMIZED: bool = false,
975 | NO_SET_FOREGROUND: bool = false,
976 | SIZE_TO_CONTENT: bool = false,
977 | _padding: u14 = 0,
978 | };
979 | pub const TASKDIALOG_COMMON_BUTTON_FLAGS = packed struct {
980 | OK_BUTTON: bool = false,
981 | YES_BUTTON: bool = false,
982 | NO_BUTTON: bool = false,
983 | CANCEL_BUTTON: bool = false,
984 | RETRY_BUTTON: bool = false,
985 | CLOSE_BUTTON: bool = false,
986 | _padding: u26 = 0,
987 | };
988 | pub const TASKDIALOG_BUTTON = extern struct {
989 | nButtonID: u32,
990 | pszButtonText: LPCWSTR,
991 | };
992 | pub const PIXELFORMATDESCRIPTOR = extern struct {
993 | nSize: WORD = @sizeOf(PIXELFORMATDESCRIPTOR),
994 | nVersion: WORD = 0,
995 | dwFlags: DWORD = 0,
996 | iPixelType: BYTE = 0,
997 | cColorBits: BYTE = 0,
998 | cRedBits: BYTE = 0,
999 | cRedShift: BYTE = 0,
1000 | cGreenBits: BYTE = 0,
1001 | cGreenShift: BYTE = 0,
1002 | cBlueBits: BYTE = 0,
1003 | cBlueShift: BYTE = 0,
1004 | cAlphaBits: BYTE = 0,
1005 | cAlphaShift: BYTE = 0,
1006 | cAccumBits: BYTE = 0,
1007 | cAccumRedBits: BYTE = 0,
1008 | cAccumGreenBits: BYTE = 0,
1009 | cAccumBlueBits: BYTE = 0,
1010 | cAccumAlphaBits: BYTE = 0,
1011 | cDepthBits: BYTE = 0,
1012 | cStencilBits: BYTE = 0,
1013 | cAuxBuffers: BYTE = 0,
1014 | iLayerType: BYTE = 0,
1015 | bReserved: BYTE = 0,
1016 | dwLayerMask: DWORD = 0,
1017 | dwVisibleMask: DWORD = 0,
1018 | dwDamageMask: DWORD = 0,
1019 | };
1020 | pub const MINMAXINFO = extern struct {
1021 | ptReserved: POINT,
1022 | ptMaxSize: POINT,
1023 | ptMaxPosition: POINT,
1024 | ptMinTrackSize: POINT,
1025 | ptMaxTrackSize: POINT,
1026 | };
1027 | pub const DEV_BROADCAST_DEVICEINTERFACE_W = extern struct {
1028 | dbcc_size: DWORD,
1029 | dbcc_devicetype: DWORD,
1030 | dbcc_reserved: DWORD,
1031 | dbcc_classguid: GUID,
1032 | dbcc_name: [1]u16,
1033 | };
1034 | pub const GUID = extern struct {
1035 | Data1: u32,
1036 | Data2: u16,
1037 | Data3: u16,
1038 | Data4: [8]u8,
1039 | };
1040 |
1041 | pub const HRESULT = i32;
1042 | pub inline fn SUCCEEDED(hr: HRESULT) bool {
1043 | return hr >= 0;
1044 | }
1045 | pub inline fn FAILED(hr: HRESULT) bool {
1046 | return hr < 0;
1047 | }
1048 |
1049 | //#region Kernel32
1050 | pub extern "Kernel32" fn GetModuleHandleW(lpModuleName: ?LPCWSTR) callconv(WINAPI) HMODULE;
1051 | pub extern "Kernel32" fn GetLastError() callconv(WINAPI) DWORD;
1052 | pub extern "Kernel32" fn SetConsoleOutputCP(wCodePageID: UINT) callconv(WINAPI) BOOL;
1053 | //#endregion
1054 |
1055 | //#region User32
1056 | pub extern "User32" fn GetSystemMetrics(nIndex: i32) callconv(WINAPI) i32;
1057 | pub extern "User32" fn CreateWindowExW(dwExtStyle: DWORD, lpClassName: ?LPCWSTR, lpWindowName: ?LPCWSTR, dwStyle: DWORD, x: i32, y: i32, nWidth: i32, nHeight: i32, hWndParent: ?HWND, hWndMenu: ?HWND, hInstance: ?HINSTANCE, lpParam: ?LPVOID) callconv(WINAPI) ?HWND;
1058 | pub extern "User32" fn DestroyWindow(hWnd: HWND) callconv(WINAPI) BOOL;
1059 | pub extern "User32" fn DefWindowProcW(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(WINAPI) LRESULT;
1060 | pub extern "User32" fn RegisterClassExW(class: *const WNDCLASSEXW) callconv(WINAPI) ATOM;
1061 | pub extern "User32" fn UnregisterClassW(lpClassName: LPCWSTR, hInstance: ?HINSTANCE) callconv(WINAPI) BOOL;
1062 | pub extern "User32" fn LoadCursorW(hInstance: ?HINSTANCE, lpCursorName: LPCWSTR) callconv(WINAPI) ?HCURSOR;
1063 | pub extern "User32" fn GetPropW(hWnd: HWND, lpString: LPCWSTR) callconv(WINAPI) ?HANDLE;
1064 | pub extern "User32" fn SetPropW(hWnd: HWND, lpString: LPCWSTR, hData: HANDLE) callconv(WINAPI) BOOL;
1065 | pub extern "User32" fn GetActiveWindow() callconv(WINAPI) ?HWND;
1066 | pub extern "User32" fn SetActiveWindow(hWnd: HWND) callconv(WINAPI) ?HWND;
1067 | pub extern "User32" fn SetFocus(hWnd: ?HWND) callconv(WINAPI) ?HWND;
1068 | pub extern "User32" fn PeekMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) callconv(WINAPI) BOOL;
1069 | pub extern "User32" fn TranslateMessage(lpMsg: *const MSG) callconv(WINAPI) BOOL;
1070 | pub extern "User32" fn DispatchMessageW(lpMsg: *const MSG) callconv(WINAPI) LRESULT;
1071 | pub extern "User32" fn ClientToScreen(hWnd: HWND, lpPoint: *POINT) callconv(WINAPI) BOOL;
1072 | pub extern "User32" fn AdjustWindowRectEx(lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD) BOOL;
1073 | pub extern "User32" fn GetClientRect(hWnd: HWND, lprect: *RECT) callconv(WINAPI) BOOL;
1074 | pub extern "User32" fn SetWindowPos(hWnd: HWND, hWndInsertAfter: ?HWND, X: i32, Y: i32, cx: i32, cy: i32, uFlags: UINT) callconv(WINAPI) BOOL;
1075 | pub extern "User32" fn GetDC(hWnd: HWND) callconv(WINAPI) ?HDC;
1076 | pub extern "User32" fn ReleaseDC(hWnd: HWND, dc: HDC) callconv(WINAPI) BOOL;
1077 | pub extern "User32" fn ShowWindow(hWnd: HWND, nCmdShow: i32) callconv(WINAPI) BOOL;
1078 | pub extern "User32" fn SetWindowTextW(hWnd: HWND, lpString: ?LPCWSTR) callconv(WINAPI) BOOL;
1079 | pub extern "User32" fn GetWindowTextLengthW(hWnd: HWND) callconv(WINAPI) i32;
1080 | pub extern "User32" fn GetWindowTextW(hWnd: HWND, lpString: LPWSTR, nMaxCount: i32) callconv(WINAPI) i32;
1081 | pub extern "User32" fn GetWindowRect(hWnd: HWND, lpRect: *RECT) callconv(WINAPI) BOOL;
1082 | pub extern "User32" fn MoveWindow(hWnd: HWND, x: i32, y: i32, nWidth: i32, nHeight: i32, bRepaint: BOOL) callconv(WINAPI) BOOL;
1083 | pub extern "User32" fn GetCursorPos(lpPoint: *POINT) callconv(WINAPI) BOOL;
1084 | pub extern "User32" fn SetCursorPos(x: i32, y: i32) callconv(WINAPI) BOOL;
1085 | pub extern "User32" fn ScreenToClient(hWnd: HWND, lpPoint: *POINT) callconv(WINAPI) BOOL;
1086 | pub extern "User32" fn SetCursor(hCurser: ?HCURSOR) callconv(WINAPI) HCURSOR;
1087 | pub extern "User32" fn ClipCursor(lpRect: ?*const RECT) callconv(WINAPI) BOOL;
1088 | pub extern "User32" fn WindowFromPoint(Point: POINT) callconv(WINAPI) ?HWND;
1089 | pub extern "User32" fn PtInRect(lprc: *const RECT, Point: POINT) callconv(WINAPI) BOOL;
1090 | pub extern "User32" fn ShowCursor(bShow: BOOL) callconv(WINAPI) i32;
1091 | pub extern "User32" fn GetKeyState(nVirtKey: i32) callconv(WINAPI) SHORT;
1092 | pub extern "User32" fn MapVirtualKeyW(uCode: UINT, uMapType: UINT) callconv(WINAPI) UINT;
1093 | pub extern "User32" fn GetMessageTime() callconv(WINAPI) LONG;
1094 | pub extern "User32" fn MessageBoxW(hWnd: ?HWND, lpText: ?LPCWSTR, lpCaption: ?LPCWSTR, uType: UINT) callconv(WINAPI) i32;
1095 | pub extern "User32" fn ToUnicode(wVirtKey: UINT, wScanCode: UINT, lpKeyState: ?*const [256]BYTE, pwszBuff: LPWSTR, cchBuff: i32, wFlags: UINT) callconv(WINAPI) i32;
1096 | pub extern "User32" fn SendMessage(hWnd: HWND, msg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(WINAPI) LRESULT;
1097 | //#endregion
1098 |
1099 | //#region Comctl32
1100 | pub extern "Comctl32" fn TaskDialogIndirect(pTaskConfig: *const TASKDIALOGCONFIG, pnButton: ?*i32, pnRadioButton: ?*i32, pfVerificationFlagChecked: ?*BOOL) callconv(WINAPI) HRESULT;
1101 | //#endregion
1102 |
1103 | //#region Opengl32
1104 | pub extern "Opengl32" fn wglCreateContext(hdc: HDC) callconv(WINAPI) ?HGLRC;
1105 | pub extern "Opengl32" fn wglDeleteContext(hglrc: HGLRC) callconv(WINAPI) BOOL;
1106 | pub extern "Opengl32" fn wglMakeCurrent(hdc: HDC, hglrc: ?HGLRC) callconv(WINAPI) BOOL;
1107 | pub extern "Opengl32" fn wglGetProcAddress(name: [*:0]const u8) callconv(WINAPI) ?*const anyopaque;
1108 | pub extern "Opengl32" fn wglShareLists(hglrc1: HGLRC, hglrc2: HGLRC) callconv(WINAPI) BOOL;
1109 | //#endregion
1110 |
1111 | //#region Gdi32
1112 | pub extern "Gdi32" fn SetPixelFormat(hdc: HDC, format: i32, ppfd: *const PIXELFORMATDESCRIPTOR) callconv(WINAPI) BOOL;
1113 | pub extern "Gdi32" fn ChoosePixelFormat(hdc: HDC, ppfd: *const PIXELFORMATDESCRIPTOR) callconv(WINAPI) i32;
1114 | pub extern "Gdi32" fn SwapBuffers(hdc: HDC) callconv(WINAPI) BOOL;
1115 | //#endregion
1116 |
--------------------------------------------------------------------------------