zephr/os: finish windows port and adjust some thing about linux

This commit is contained in:
2024-01-26 01:32:54 +02:00
committed by Illusion
parent 69e962a197
commit 07d1be7d51
3 changed files with 260 additions and 347 deletions
+21 -92
View File
@@ -7,6 +7,8 @@ import x11 "vendor:x11/xlib"
import "../glx" import "../glx"
import "../xcursor" import "../xcursor"
OsEvent :: x11.Cursor
@(private="file") @(private="file")
PropModeReplace :: 0 PropModeReplace :: 0
@(private="file") @(private="file")
@@ -32,8 +34,7 @@ x11_go_fullscreen :: proc() {
// and properly fullscreen the window // and properly fullscreen the window
size_hints := x11.XAllocSizeHints() size_hints := x11.XAllocSizeHints()
zephr_ctx.window.pre_fullscreen_size.x = zephr_ctx.window.size.x zephr_ctx.window.pre_fullscreen_size = zephr_ctx.window.size
zephr_ctx.window.pre_fullscreen_size.y = zephr_ctx.window.size.y
if (size_hints != nil) { if (size_hints != nil) {
size_hints.flags = {.PPosition, .PSize} size_hints.flags = {.PPosition, .PSize}
size_hints.width = cast(i32)zephr_ctx.window.size.x size_hints.width = cast(i32)zephr_ctx.window.size.x
@@ -299,94 +300,6 @@ backend_shutdown :: proc() {
x11.XCloseDisplay(x11_display) x11.XCloseDisplay(x11_display)
} }
@(private="file")
x11_mods_to_zephr_mods :: proc(scancode: Scancode, is_press: bool) -> KeyMod {
mods := zephr_ctx.keyboard.mods
if (is_press) {
if (scancode == .LEFT_SHIFT) {
mods |= {.LEFT_SHIFT, .SHIFT}
}
if (scancode == .RIGHT_SHIFT) {
mods |= {.RIGHT_SHIFT, .SHIFT}
}
if (scancode == .LEFT_CTRL) {
mods |= {.LEFT_CTRL, .CTRL}
}
if (scancode == .RIGHT_CTRL) {
mods |= {.RIGHT_CTRL, .CTRL}
}
if (scancode == .LEFT_ALT) {
mods |= {.LEFT_ALT, .ALT}
}
if (scancode == .RIGHT_ALT) {
mods |= {.RIGHT_ALT, .ALT}
}
if (scancode == .LEFT_META) {
mods |= {.LEFT_META, .META}
}
if (scancode == .RIGHT_META) {
mods |= {.RIGHT_META, .META}
}
if (scancode == .CAPS_LOCK) {
mods |= {.CAPS_LOCK}
}
if (scancode == .NUM_LOCK_OR_CLEAR) {
mods |= {.NUM_LOCK}
}
} else {
if (scancode == .LEFT_SHIFT) {
mods &= ~{.LEFT_SHIFT}
}
if (scancode == .RIGHT_SHIFT) {
mods &= ~{.RIGHT_SHIFT}
}
if (!(.RIGHT_SHIFT in mods) && !(.LEFT_SHIFT in mods)) {
mods &= ~{.SHIFT}
}
if (scancode == .LEFT_CTRL) {
mods &= ~{.LEFT_CTRL}
}
if (scancode == .RIGHT_CTRL) {
mods &= ~{.RIGHT_CTRL}
}
if (!(.RIGHT_CTRL in mods) && !(.LEFT_CTRL in mods)) {
mods &= ~{.CTRL}
}
if (scancode == .LEFT_ALT) {
mods &= ~{.LEFT_ALT}
}
if (scancode == .RIGHT_ALT) {
mods &= ~{.RIGHT_ALT}
}
if (!(.RIGHT_ALT in mods) && !(.LEFT_ALT in mods)) {
mods &= ~{.ALT}
}
if (scancode == .LEFT_META) {
mods &= ~{.LEFT_META}
}
if (scancode == .RIGHT_META) {
mods &= ~{.RIGHT_META}
}
if (!(.RIGHT_META in mods) && !(.LEFT_META in mods)) {
mods &= ~{.META}
}
if (scancode == .CAPS_LOCK) {
mods &= ~{.CAPS_LOCK}
}
if (scancode == .NUM_LOCK_OR_CLEAR) {
mods &= ~{.NUM_LOCK}
}
}
zephr_ctx.keyboard.mods = mods
return mods
}
backend_swapbuffers :: proc() { backend_swapbuffers :: proc() {
glx.SwapBuffers(x11_display, x11_window) glx.SwapBuffers(x11_display, x11_window)
} }
@@ -435,7 +348,7 @@ backend_get_os_events :: proc(e_out: ^Event) -> bool {
e_out.type = .KEY_PRESSED e_out.type = .KEY_PRESSED
e_out.key.scancode = scancode e_out.key.scancode = scancode
//e_out.key.code = keycode; //e_out.key.code = keycode;
e_out.key.mods = x11_mods_to_zephr_mods(scancode, true) e_out.key.mods = set_zephr_mods(scancode, true)
return true return true
} else if xev.type == .KeyRelease { } else if xev.type == .KeyRelease {
@@ -447,7 +360,7 @@ backend_get_os_events :: proc(e_out: ^Event) -> bool {
e_out.type = .KEY_RELEASED e_out.type = .KEY_RELEASED
e_out.key.scancode = scancode e_out.key.scancode = scancode
//e_out.key.code = keycode; //e_out.key.code = keycode;
e_out.key.mods = x11_mods_to_zephr_mods(scancode, false) e_out.key.mods = set_zephr_mods(scancode, false)
return true return true
} else if xev.type == .ButtonPress { } else if xev.type == .ButtonPress {
@@ -531,3 +444,19 @@ backend_get_os_events :: proc(e_out: ^Event) -> bool {
return false return false
} }
backend_set_cursor :: proc() {
x11.XDefineCursor(x11_display, x11_window, zephr_ctx.cursors[zephr_ctx.cursor])
}
backend_init_cursors :: proc() {
zephr_ctx.cursors[.ARROW] = x11.XCreateFontCursor(x11_display, .XC_left_ptr)
zephr_ctx.cursors[.IBEAM] = x11.XCreateFontCursor(x11_display, .XC_xterm)
zephr_ctx.cursors[.CROSSHAIR] = x11.XCreateFontCursor(x11_display, .XC_crosshair)
zephr_ctx.cursors[.HAND] = x11.XCreateFontCursor(x11_display, .XC_hand1)
zephr_ctx.cursors[.HRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_h_double_arrow)
zephr_ctx.cursors[.VRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_v_double_arrow)
non-standard cursors
zephr_ctx.cursors[.DISABLED] = xcursor.LibraryLoadCursor(x11_display, "crossed_circle")
}
+146 -106
View File
@@ -3,7 +3,6 @@
package zephr package zephr
import "core:log" import "core:log"
import "core:fmt"
import "core:strings" import "core:strings"
import "core:strconv" import "core:strconv"
import "core:os" import "core:os"
@@ -12,6 +11,15 @@ import win32 "core:sys/windows"
import gl "vendor:OpenGL" import gl "vendor:OpenGL"
// BUG: setting the cursor every frame messes with the cursor for resizing when on the edge of the window
// TODO: handle start window in fullscreen
// currently the way to "start" a window in fullscreen is to just create a regular window
// and immediately fullscreen it. This works fine but there's a moment where you can see the regular-sized window.
// Not a priority right now.
// TODO: only log debug when ODIN_DEBUG is true
OsCursor :: win32.HCURSOR
OsEvent :: struct { OsEvent :: struct {
type: win32.UINT, type: win32.UINT,
lparam: win32.LPARAM, lparam: win32.LPARAM,
@@ -41,7 +49,33 @@ backend_get_screen_size :: proc() -> Vec2 {
} }
backend_toggle_fullscreen :: proc(fullscreen: bool) { backend_toggle_fullscreen :: proc(fullscreen: bool) {
// TODO: context.logger = logger
// TODO: handle multiple monitors
if fullscreen {
w := cast(i32)zephr_ctx.window.pre_fullscreen_size.x
h := cast(i32)zephr_ctx.window.pre_fullscreen_size.y
win_style := (win32.WS_OVERLAPPEDWINDOW if !zephr_ctx.window.non_resizable else win32.WS_OVERLAPPEDWINDOW & ~win32.WS_MAXIMIZEBOX & ~win32.WS_THICKFRAME) | win32.WS_VISIBLE
// Adjust the rect to account for the window titlebar and frame sizes
rect := win32.RECT{0, 0, w, h}
win32.AdjustWindowRect(&rect, win_style, false)
w = rect.right - rect.left
h = rect.bottom - rect.top
x := cast(i32)(zephr_ctx.screen_size.x / 2 - cast(f32)w / 2)
y := cast(i32)(zephr_ctx.screen_size.y / 2 - cast(f32)h / 2)
win32.SetWindowLongPtrW(hwnd, win32.GWL_STYLE, cast(win32.LONG_PTR)(win_style))
win32.SetWindowPos(hwnd, nil, x, y, w, h, win32.SWP_FRAMECHANGED)
} else {
zephr_ctx.window.pre_fullscreen_size = zephr_ctx.window.size
w := cast(i32)zephr_ctx.screen_size.x
h := cast(i32)zephr_ctx.screen_size.y
result := win32.SetWindowLongPtrW(hwnd, win32.GWL_STYLE, cast(win32.LONG_PTR)(win32.WS_VISIBLE | win32.WS_POPUPWINDOW))
win32.SetWindowPos(hwnd, win32.HWND_TOP, 0, 0, w, h, win32.SWP_FRAMECHANGED)
}
} }
@(private="file") @(private="file")
@@ -116,7 +150,7 @@ init_legacy_gl :: proc(class_name: win32.wstring, hInstance: win32.HINSTANCE) {
} }
@(private="file") @(private="file")
init_gl :: proc(class_name: win32.wstring, window_title: win32.wstring, window_size: Vec2, hInstance: win32.HINSTANCE) { init_gl :: proc(class_name: win32.wstring, window_title: win32.wstring, window_size: Vec2, window_non_resizable: bool, hInstance: win32.HINSTANCE) {
screen_size := Vec2{ screen_size := Vec2{
cast(f32)win32.GetSystemMetrics(win32.SM_CXSCREEN), cast(f32)win32.GetSystemMetrics(win32.SM_CXSCREEN),
cast(f32)win32.GetSystemMetrics(win32.SM_CYSCREEN), cast(f32)win32.GetSystemMetrics(win32.SM_CYSCREEN),
@@ -131,11 +165,13 @@ init_gl :: proc(class_name: win32.wstring, window_title: win32.wstring, window_s
win_width := rect.right - rect.left win_width := rect.right - rect.left
win_height := rect.bottom - rect.top win_height := rect.bottom - rect.top
hwnd := win32.CreateWindowExW( win_style := win32.WS_OVERLAPPEDWINDOW if !window_non_resizable else (win32.WS_OVERLAPPEDWINDOW & ~win32.WS_THICKFRAME & ~win32.WS_MAXIMIZEBOX)
hwnd = win32.CreateWindowExW(
0, 0,
class_name, class_name,
window_title, window_title,
win32.WS_OVERLAPPEDWINDOW, win_style,
cast(i32)win_x, cast(i32)win_y, win_width, win_height, cast(i32)win_x, cast(i32)win_y, win_width, win_height,
@@ -165,9 +201,7 @@ init_gl :: proc(class_name: win32.wstring, window_title: win32.wstring, window_s
win32.WGL_DRAW_TO_WINDOW_ARB, 1, win32.WGL_DRAW_TO_WINDOW_ARB, 1,
win32.WGL_SUPPORT_OPENGL_ARB, 1, win32.WGL_SUPPORT_OPENGL_ARB, 1,
win32.WGL_DOUBLE_BUFFER_ARB, 1, win32.WGL_DOUBLE_BUFFER_ARB, 1,
// TODO: test to see if EXCHANGE actually causes problems in fullscreen win32.WGL_SWAP_METHOD_ARB, win32.WGL_SWAP_EXCHANGE_ARB,
/* WGL_SWAP_EXCHANGE_ARB causes problems with window menu in fullscreen */
win32.WGL_SWAP_METHOD_ARB, win32.WGL_SWAP_COPY_ARB,
win32.WGL_PIXEL_TYPE_ARB, win32.WGL_TYPE_RGBA_ARB, win32.WGL_PIXEL_TYPE_ARB, win32.WGL_TYPE_RGBA_ARB,
win32.WGL_ACCELERATION_ARB, win32.WGL_FULL_ACCELERATION_ARB, win32.WGL_ACCELERATION_ARB, win32.WGL_FULL_ACCELERATION_ARB,
win32.WGL_COLOR_BITS_ARB, 32, win32.WGL_COLOR_BITS_ARB, 32,
@@ -318,7 +352,7 @@ backend_init :: proc(window_title: cstring, window_size: Vec2, icon_path: cstrin
win32.SetProcessDpiAwarenessContext(win32.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) win32.SetProcessDpiAwarenessContext(win32.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
init_legacy_gl(class_name, hInstance) init_legacy_gl(class_name, hInstance)
init_gl(class_name, window_title, window_size, hInstance) init_gl(class_name, window_title, window_size, window_non_resizable, hInstance)
} }
backend_get_os_events :: proc(e_out: ^Event) -> bool { backend_get_os_events :: proc(e_out: ^Event) -> bool {
@@ -441,20 +475,26 @@ backend_get_os_events :: proc(e_out: ^Event) -> bool {
return true return true
case win32.WM_SYSKEYDOWN: fallthrough case win32.WM_SYSKEYDOWN: fallthrough
case win32.WM_KEYDOWN: case win32.WM_KEYDOWN:
log.debug(event.lparam)
// Bits 16-23 hold the scancode // Bits 16-23 hold the scancode
system_scancode := (event.lparam & 0xFF0000) >> 16 system_scancode := (event.lparam & 0xFF0000) >> 16
is_extended := event.lparam & (1 << 24) != 0
scancode := scan1_scancode_to_zephr_scancode_map[system_scancode] scancode := scan1_scancode_to_zephr_scancode_map(auto_cast system_scancode, is_extended)
log.debug(system_scancode) e_out.key.scancode = scancode
log.debug(scancode) e_out.key.mods = set_zephr_mods(scancode, true)
// TODO: return true
case win32.WM_SYSKEYUP: fallthrough case win32.WM_SYSKEYUP: fallthrough
case win32.WM_KEYUP: case win32.WM_KEYUP:
// TODO: // Bits 16-23 hold the scancode
// 0101 0010 system_scancode := (event.lparam & 0xFF0000) >> 16
//log.debug("released key") is_extended := event.lparam & (1 << 24) != 0
scancode := scan1_scancode_to_zephr_scancode_map(auto_cast system_scancode, is_extended)
e_out.key.scancode = scancode
e_out.key.mods = set_zephr_mods(scancode, false)
return true
} }
} }
@@ -476,6 +516,8 @@ backend_swapbuffers :: proc() {
// https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
@(private="file") @(private="file")
scan1_scancode_to_zephr_scancode_map :: proc(scancode: u8, is_extended: bool) -> Scancode { scan1_scancode_to_zephr_scancode_map :: proc(scancode: u8, is_extended: bool) -> Scancode {
context.logger = logger
switch scancode { switch scancode {
case 0: return .NULL case 0: return .NULL
@@ -517,7 +559,7 @@ scan1_scancode_to_zephr_scancode_map :: proc(scancode: u8, is_extended: bool) ->
case 0x0A: return .KEY_9 case 0x0A: return .KEY_9
case 0x0B: return .KEY_0 case 0x0B: return .KEY_0
case 0x1C: return .ENTER case 0x1C: return .KP_ENTER if is_extended else .ENTER
case 0x01: return .ESCAPE case 0x01: return .ESCAPE
case 0x0E: return .BACKSPACE // Says "Keyboard Delete" on microsoft.com but it's actually backspace case 0x0E: return .BACKSPACE // Says "Keyboard Delete" on microsoft.com but it's actually backspace
case 0x0F: return .TAB case 0x0F: return .TAB
@@ -534,7 +576,7 @@ scan1_scancode_to_zephr_scancode_map :: proc(scancode: u8, is_extended: bool) ->
case 0x29: return .GRAVE case 0x29: return .GRAVE
case 0x33: return .COMMA case 0x33: return .COMMA
case 0x34: return .PERIOD case 0x34: return .PERIOD
case 0x35: return .SLASH case 0x35: return .KP_DIVIDE if is_extended else .SLASH
case 0x3A: return .CAPS_LOCK case 0x3A: return .CAPS_LOCK
@@ -551,97 +593,95 @@ scan1_scancode_to_zephr_scancode_map :: proc(scancode: u8, is_extended: bool) ->
case 0x57: return .F11 case 0x57: return .F11
case 0x58: return .F12 case 0x58: return .F12
case 0x54: return .PRINT_SCREEN case 0x54: return .PRINT_SCREEN // Only emitted on KeyRelease
//case 0xE037 = .PRINT_SCREEN, // SysRq ??? case 0x46: return .PAUSE if is_extended else .SCROLL_LOCK
case 0x46: return .SCROLL_LOCK case 0x45: return .NUM_LOCK_OR_CLEAR if is_extended else .PAUSE
case 0x45: return .PAUSE
//case 0xE046 = .PAUSE, // Break ??
//case 0xE11D45 = .PAUSE, // Some legacy stuff ??? //case 0xE11D45 = .PAUSE, // Some legacy stuff ???
case 0x52: case 0x52: return .INSERT if is_extended else .KP_0
// INSERT case 0x47: return .HOME if is_extended else .KP_7
// KP_0 case 0x49: return .PAGE_UP if is_extended else .KP_9
case 0x47: case 0x53: return .DELETE if is_extended else .KP_PERIOD
// HOME case 0x4F: return .END if is_extended else .KP_1
// KP_7 case 0x51: return .PAGE_DOWN if is_extended else .KP_3
case 0x49: case 0x4D: return .RIGHT if is_extended else .KP_6
// PAGE_UP case 0x4B: return .LEFT if is_extended else .KP_4
// KP_9 case 0x50: return .DOWN if is_extended else .KP_2
case 0x53: case 0x48: return .UP if is_extended else .KP_8
// DELETE case 0x37: return .PRINT_SCREEN if is_extended else .KP_MULTIPLY
// KP_PERIOD case 0x4A: return .KP_MINUS
case 0x4F: case 0x4E: return .KP_PLUS
// END case 0x4C: return .KP_5
// KP_1
case 0x51: case 0x56: return .NON_US_BACKSLASH
// PAGE_DOWN case 0x5D:
// KP_3 if is_extended {
case 0x4D: return .APPLICATION
// RIGHT } else {
// KP_6 log.warnf("Pressed unmapped key: %d. Extended key: %s", scancode, is_extended)
case 0x4B:
// LEFT
// KP_4
case 0x50:
// DOWN
// KP_2
case 0xE048:
// UP
// KP_8
} }
case 0x5E:
if is_extended {
return .POWER
} else {
log.warnf("Pressed unmapped key: %d. Extended key: %s", scancode, is_extended)
}
case 0x59: return .KP_EQUALS
case 0x64: return .F13
case 0x65: return .F14
case 0x66: return .F15
case 0x67: return .F16
case 0x68: return .F17
case 0x69: return .F18
case 0x6A: return .F19
case 0x6B: return .F20
case 0x6C: return .F21
case 0x6D: return .F22
case 0x6E: return .F23
case 0x76: return .F24
case 0x7E: return .KP_COMMA
case 0x73: return .INTERNATIONAL1
case 0x70: return .INTERNATIONAL2
case 0x7D: return .INTERNATIONAL3
case 0x79: return .INTERNATIONAL4
case 0x7B: return .INTERNATIONAL5
case 0x5C: return .RIGHT_META if is_extended else .INTERNATIONAL6
case 0x72: return .LANG1 // Only emitted on Key Release
case 0xF2: return .LANG1 // Legacy, Only emitted on Key Release
case 0x71: return .LANG2 // Only emitted on Key Release
case 0xF1: return .LANG2 // Legacy, Only emitted on Key Release
case 0x78: return .LANG3
case 0x77: return .LANG4
//case 0x76: return .LANG5 // Conflicts with F24
case 0x1D: return .RIGHT_CTRL if is_extended else .LEFT_CTRL
case 0x2A: return .LEFT_SHIFT
case 0x36: return .RIGHT_SHIFT
//0x45 = .NUM_LOCK_OR_CLEAR, // conflicts with Pause, Pause doesn't have the extended bit set. don't know about this case 0x38: return .RIGHT_ALT if is_extended else .LEFT_ALT
//0xE045 = .NUM_LOCK_OR_CLEAR, // Legacy stuff case 0x5B:
0xE035 = .KP_DIVIDE, if is_extended {
0x37 = .KP_MULTIPLY, return .LEFT_META
0x4A = .KP_MINUS, } else {
0x4E = .KP_PLUS, log.warnf("Pressed unmapped key: %d. Extended key: %s", scancode, is_extended)
0xE01C = .KP_ENTER, }
0x4C = .KP_5,
0x56 = .NON_US_BACKSLASH,
0xE05D = .APPLICATION,
0xE05E = .POWER,
0x59 = .KP_EQUALS,
0x64 = .F13,
0x65 = .F14,
0x66 = .F15,
0x67 = .F16,
0x68 = .F17,
0x69 = .F18,
0x6A = .F19,
0x6B = .F20,
0x6C = .F21,
0x6D = .F22,
0x6E = .F23,
0x76 = .F24,
0x7E = .KP_COMMA,
0x73 = .INTERNATIONAL1,
0x70 = .INTERNATIONAL2,
0x7D = .INTERNATIONAL3,
0x79 = .INTERNATIONAL4,
0x7B = .INTERNATIONAL5,
0x5C = .INTERNATIONAL6,
0x72 = .LANG1, // Only emitted on Key Release
0xF2 = .LANG1, // Legacy, Only emitted on Key Release
0x71 = .LANG2, // Only emitted on Key Release
0xF1 = .LANG2, // Legacy, Only emitted on Key Release
0x78 = .LANG3,
0x77 = .LANG4,
//0x76 = .LANG5, // Conflicts with F24
0x1D = .LEFT_CTRL,
0x2A = .LEFT_SHIFT,
0x38 = .LEFT_ALT,
0xE05B = .LEFT_META,
0xE01D = .RIGHT_CTRL,
0x36 = .RIGHT_SHIFT,
0xE038 = .RIGHT_ALT,
0xE05C = .RIGHT_META,
// End of Keyboard/Keypad section on microsoft.com // End of Keyboard/Keypad section on microsoft.com
// We currently don't map or care about the Consumer section // We currently don't map or care about the Consumer section
}
return .NULL
}
backend_set_cursor :: proc() {
win32.SetCursor(zephr_ctx.cursors[zephr_ctx.cursor])
}
backend_init_cursors :: proc() {
zephr_ctx.cursors[.ARROW] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_ARROW, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.IBEAM] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_IBEAM, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.CROSSHAIR] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_CROSS, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.HAND] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_HAND, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.HRESIZE] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_SIZEWE, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.VRESIZE] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_SIZENS, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
zephr_ctx.cursors[.DISABLED] = auto_cast win32.LoadImageW(nil, auto_cast win32._IDC_NO, win32.IMAGE_CURSOR, 0, 0, win32.LR_DEFAULTSIZE | win32.LR_SHARED)
} }
+92 -148
View File
@@ -356,7 +356,7 @@ Context :: struct {
keyboard: Keyboard, keyboard: Keyboard,
cursor: Cursor, cursor: Cursor,
event_queue: queue.Queue(OsEvent), event_queue: queue.Queue(OsEvent),
//cursors: [Cursor]x11.Cursor, cursors: [Cursor]OsCursor,
ui: Ui, ui: Ui,
/* ZephrKeyboard keyboard; */ /* ZephrKeyboard keyboard; */
@@ -666,15 +666,7 @@ init :: proc(font_path: cstring, icon_path: cstring, window_title: cstring, wind
zephr_ctx.window.non_resizable = window_non_resizable zephr_ctx.window.non_resizable = window_non_resizable
zephr_ctx.projection = orthographic_projection_2d(0, window_size.x, window_size.y, 0) zephr_ctx.projection = orthographic_projection_2d(0, window_size.x, window_size.y, 0)
// zephr_ctx.cursors[.ARROW] = x11.XCreateFontCursor(x11_display, .XC_left_ptr) backend_init_cursors()
// zephr_ctx.cursors[.IBEAM] = x11.XCreateFontCursor(x11_display, .XC_xterm)
// zephr_ctx.cursors[.CROSSHAIR] = x11.XCreateFontCursor(x11_display, .XC_crosshair)
// zephr_ctx.cursors[.HAND] = x11.XCreateFontCursor(x11_display, .XC_hand1)
// zephr_ctx.cursors[.HRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_h_double_arrow)
// zephr_ctx.cursors[.VRESIZE] = x11.XCreateFontCursor(x11_display, .XC_sb_v_double_arrow)
// non-standard cursors
// zephr_ctx.cursors[.DISABLED] = xcursor.LibraryLoadCursor(x11_display, "crossed_circle")
zephr_ctx.screen_size = backend_get_screen_size() zephr_ctx.screen_size = backend_get_screen_size()
start_internal_timer() start_internal_timer()
@@ -727,150 +719,13 @@ swap_buffers :: proc() {
} }
backend_swapbuffers() backend_swapbuffers()
//x11.XDefineCursor(x11_display, x11_window, zephr_ctx.cursors[zephr_ctx.cursor]) backend_set_cursor()
} }
iter_events :: proc(e_out: ^Event) -> bool { iter_events :: proc(e_out: ^Event) -> bool {
return backend_get_os_events(e_out) return backend_get_os_events(e_out)
} }
// iter_events :: proc(e_out: ^Event) -> bool {
// context.logger = logger
// xev: x11.XEvent
// for (cast(bool)x11.XPending(x11_display)) {
// x11.XNextEvent(x11_display, &xev)
// if xev.type == .ConfigureNotify {
// xce := xev.xconfigure
// if (xce.width != cast(i32)zephr_ctx.window.size.x || xce.height != cast(i32)zephr_ctx.window.size.y) {
// zephr_ctx.window.size = Vec2{cast(f32)xce.width, cast(f32)xce.height}
// zephr_ctx.projection = orthographic_projection_2d(0, zephr_ctx.window.size.x, zephr_ctx.window.size.y, 0)
// x11_resize_window()
// e_out.type = .WINDOW_RESIZED
// e_out.window.width = cast(u32)xce.width
// e_out.window.height = cast(u32)xce.height
// return true
// }
// } else if xev.type == .DestroyNotify {
// // window destroy event
// e_out.type = .WINDOW_CLOSED
// return true
// } else if xev.type == .ClientMessage {
// // window close event
// if (cast(x11.Atom)xev.xclient.data.l[0] == zephr_ctx.window_delete_atom) {
// e_out.type = .WINDOW_CLOSED
// return true
// }
// } else if xev.type == .KeyPress {
// xke := xev.xkey
// evdev_keycode := xke.keycode - 8
// scancode := evdev_scancode_to_zephr_scancode_map[evdev_keycode]
// e_out.type = .KEY_PRESSED
// e_out.key.scancode = scancode
// //e_out.key.code = keycode;
// e_out.key.mods = x11_mods_to_zephr_mods(scancode, true)
// return true
// } else if xev.type == .KeyRelease {
// xke := xev.xkey
// evdev_keycode := xke.keycode - 8
// scancode := evdev_scancode_to_zephr_scancode_map[evdev_keycode]
// e_out.type = .KEY_RELEASED
// e_out.key.scancode = scancode
// //e_out.key.code = keycode;
// e_out.key.mods = x11_mods_to_zephr_mods(scancode, false)
// return true
// } else if xev.type == .ButtonPress {
// e_out.type = .MOUSE_BUTTON_PRESSED
// e_out.mouse.pos = Vec2{cast(f32)xev.xbutton.x, cast(f32)xev.xbutton.y}
// zephr_ctx.mouse.pressed = true
// switch (xev.xbutton.button) {
// case .Button1:
// e_out.mouse.button = .BUTTON_LEFT
// zephr_ctx.mouse.button = .BUTTON_LEFT
// case .Button2:
// e_out.mouse.button = .BUTTON_MIDDLE
// zephr_ctx.mouse.button = .BUTTON_MIDDLE
// case .Button3:
// e_out.mouse.button = .BUTTON_RIGHT
// zephr_ctx.mouse.button = .BUTTON_RIGHT
// case .Button4:
// e_out.type = .MOUSE_SCROLL
// e_out.mouse.scroll_direction = .UP
// case .Button5:
// e_out.type = .MOUSE_SCROLL
// e_out.mouse.scroll_direction = .DOWN
// case cast(x11.MouseButton)8: // Back
// e_out.mouse.button = .BUTTON_BACK
// zephr_ctx.mouse.button = .BUTTON_BACK
// case cast(x11.MouseButton)9: // Forward
// e_out.mouse.button = .BUTTON_FORWARD
// zephr_ctx.mouse.button = .BUTTON_FORWARD
// case:
// log.warnf("Unknown mouse button pressed: %d", xev.xbutton.button)
// }
// return true
// } else if xev.type == .ButtonRelease {
// e_out.type = .MOUSE_BUTTON_RELEASED
// e_out.mouse.pos = Vec2{cast(f32)xev.xbutton.x, cast(f32)xev.xbutton.y}
// zephr_ctx.mouse.released = true
// zephr_ctx.mouse.pressed = false
// switch (xev.xbutton.button) {
// case .Button1:
// e_out.mouse.button = .BUTTON_LEFT
// case .Button2:
// e_out.mouse.button = .BUTTON_MIDDLE
// case .Button3:
// e_out.mouse.button = .BUTTON_RIGHT
// case .Button4:
// e_out.type = .MOUSE_SCROLL
// e_out.mouse.scroll_direction = .UP
// case .Button5:
// e_out.type = .MOUSE_SCROLL
// e_out.mouse.scroll_direction = .DOWN
// case cast(x11.MouseButton)8: // Back
// e_out.mouse.button = .BUTTON_BACK
// zephr_ctx.mouse.button = .BUTTON_BACK
// case cast(x11.MouseButton)9: // Forward
// e_out.mouse.button = .BUTTON_FORWARD
// zephr_ctx.mouse.button = .BUTTON_FORWARD
// }
// return true
// } else if xev.type == .MappingNotify {
// // input device mapping changed
// if (xev.xmapping.request != .MappingKeyboard) {
// break
// }
// x11.XRefreshKeyboardMapping(&xev.xmapping)
// /* x11_keyboard_map_update(); */
// break
// } else if xev.type == .MotionNotify {
// e_out.type = .MOUSE_MOVED
// e_out.mouse.pos = Vec2{cast(f32)xev.xmotion.x, cast(f32)xev.xmotion.y}
// zephr_ctx.mouse.pos = e_out.mouse.pos
// return true
// }
// }
// return false
// }
get_window_size :: proc() -> Vec2 { get_window_size :: proc() -> Vec2 {
return zephr_ctx.window.size return zephr_ctx.window.size
} }
@@ -924,3 +779,92 @@ logger_init :: proc() {
logger = log.create_multi_logger(file_logger, term_logger) logger = log.create_multi_logger(file_logger, term_logger)
} }
@private
set_zephr_mods :: proc(scancode: Scancode, is_press: bool) -> KeyMod {
mods := zephr_ctx.keyboard.mods
if (is_press) {
if (scancode == .LEFT_SHIFT) {
mods |= {.LEFT_SHIFT, .SHIFT}
}
if (scancode == .RIGHT_SHIFT) {
mods |= {.RIGHT_SHIFT, .SHIFT}
}
if (scancode == .LEFT_CTRL) {
mods |= {.LEFT_CTRL, .CTRL}
}
if (scancode == .RIGHT_CTRL) {
mods |= {.RIGHT_CTRL, .CTRL}
}
if (scancode == .LEFT_ALT) {
mods |= {.LEFT_ALT, .ALT}
}
if (scancode == .RIGHT_ALT) {
mods |= {.RIGHT_ALT, .ALT}
}
if (scancode == .LEFT_META) {
mods |= {.LEFT_META, .META}
}
if (scancode == .RIGHT_META) {
mods |= {.RIGHT_META, .META}
}
if (scancode == .CAPS_LOCK) {
mods |= {.CAPS_LOCK}
}
if (scancode == .NUM_LOCK_OR_CLEAR) {
mods |= {.NUM_LOCK}
}
} else {
if (scancode == .LEFT_SHIFT) {
mods &= ~{.LEFT_SHIFT}
}
if (scancode == .RIGHT_SHIFT) {
mods &= ~{.RIGHT_SHIFT}
}
if (!(.RIGHT_SHIFT in mods) && !(.LEFT_SHIFT in mods)) {
mods &= ~{.SHIFT}
}
if (scancode == .LEFT_CTRL) {
mods &= ~{.LEFT_CTRL}
}
if (scancode == .RIGHT_CTRL) {
mods &= ~{.RIGHT_CTRL}
}
if (!(.RIGHT_CTRL in mods) && !(.LEFT_CTRL in mods)) {
mods &= ~{.CTRL}
}
if (scancode == .LEFT_ALT) {
mods &= ~{.LEFT_ALT}
}
if (scancode == .RIGHT_ALT) {
mods &= ~{.RIGHT_ALT}
}
if (!(.RIGHT_ALT in mods) && !(.LEFT_ALT in mods)) {
mods &= ~{.ALT}
}
if (scancode == .LEFT_META) {
mods &= ~{.LEFT_META}
}
if (scancode == .RIGHT_META) {
mods &= ~{.RIGHT_META}
}
if (!(.RIGHT_META in mods) && !(.LEFT_META in mods)) {
mods &= ~{.META}
}
if (scancode == .CAPS_LOCK) {
mods &= ~{.CAPS_LOCK}
}
if (scancode == .NUM_LOCK_OR_CLEAR) {
mods &= ~{.NUM_LOCK}
}
}
zephr_ctx.keyboard.mods = mods
return mods
}