oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,639 bytes raw
1
const std = @import("std");
2
const testing = std.testing;
3
4
const Mod4Mask: u32 = 1 << 6;
5
const Mod1Mask: u32 = 1 << 3;
6
const ShiftMask: u32 = 1 << 0;
7
const ControlMask: u32 = 1 << 2;
8
9
fn parse_modifier(name: []const u8) u32 {
10
    if (std.mem.eql(u8, name, "Mod4") or std.mem.eql(u8, name, "mod4") or std.mem.eql(u8, name, "super")) {
11
        return Mod4Mask;
12
    } else if (std.mem.eql(u8, name, "Mod1") or std.mem.eql(u8, name, "mod1") or std.mem.eql(u8, name, "alt")) {
13
        return Mod1Mask;
14
    } else if (std.mem.eql(u8, name, "Shift") or std.mem.eql(u8, name, "shift")) {
15
        return ShiftMask;
16
    } else if (std.mem.eql(u8, name, "Control") or std.mem.eql(u8, name, "control") or std.mem.eql(u8, name, "ctrl")) {
17
        return ControlMask;
18
    }
19
    return 0;
20
}
21
22
fn parse_modifiers(names: []const []const u8) u32 {
23
    var mask: u32 = 0;
24
    for (names) |name| {
25
        mask |= parse_modifier(name);
26
    }
27
    return mask;
28
}
29
30
test "parse_modifier: Mod4 variants" {
31
    try testing.expectEqual(Mod4Mask, parse_modifier("Mod4"));
32
    try testing.expectEqual(Mod4Mask, parse_modifier("mod4"));
33
    try testing.expectEqual(Mod4Mask, parse_modifier("super"));
34
}
35
36
test "parse_modifier: Mod1 (Alt) variants" {
37
    try testing.expectEqual(Mod1Mask, parse_modifier("Mod1"));
38
    try testing.expectEqual(Mod1Mask, parse_modifier("mod1"));
39
    try testing.expectEqual(Mod1Mask, parse_modifier("alt"));
40
}
41
42
test "parse_modifier: Shift variants" {
43
    try testing.expectEqual(ShiftMask, parse_modifier("Shift"));
44
    try testing.expectEqual(ShiftMask, parse_modifier("shift"));
45
}
46
47
test "parse_modifier: Control variants" {
48
    try testing.expectEqual(ControlMask, parse_modifier("Control"));
49
    try testing.expectEqual(ControlMask, parse_modifier("control"));
50
    try testing.expectEqual(ControlMask, parse_modifier("ctrl"));
51
}
52
53
test "parse_modifier: unknown returns 0" {
54
    try testing.expectEqual(@as(u32, 0), parse_modifier("Unknown"));
55
    try testing.expectEqual(@as(u32, 0), parse_modifier(""));
56
}
57
58
test "parse_modifiers: combines multiple modifiers" {
59
    const mods = &[_][]const u8{ "Mod4", "Shift" };
60
    try testing.expectEqual(Mod4Mask | ShiftMask, parse_modifiers(mods));
61
}
62
63
test "parse_modifiers: triple combination" {
64
    const mods = &[_][]const u8{ "super", "shift", "ctrl" };
65
    try testing.expectEqual(Mod4Mask | ShiftMask | ControlMask, parse_modifiers(mods));
66
}
67
68
test "parse_modifiers: empty list returns 0" {
69
    const mods = &[_][]const u8{};
70
    try testing.expectEqual(@as(u32, 0), parse_modifiers(mods));
71
}
72
73
fn key_name_to_keysym(name: []const u8) ?u64 {
74
    const key_map = .{
75
        .{ "Return", 0xff0d },
76
        .{ "Enter", 0xff0d },
77
        .{ "Tab", 0xff09 },
78
        .{ "Escape", 0xff1b },
79
        .{ "BackSpace", 0xff08 },
80
        .{ "Delete", 0xffff },
81
        .{ "space", 0x0020 },
82
        .{ "Space", 0x0020 },
83
    };
84
85
    inline for (key_map) |entry| {
86
        if (std.mem.eql(u8, name, entry[0])) {
87
            return entry[1];
88
        }
89
    }
90
91
    if (name.len == 1) {
92
        const char = name[0];
93
        if (char >= 'a' and char <= 'z') {
94
            return char;
95
        }
96
        if (char >= 'A' and char <= 'Z') {
97
            return char + 32;
98
        }
99
        if (char >= '0' and char <= '9') {
100
            return char;
101
        }
102
    }
103
104
    return null;
105
}
106
107
test "key_name_to_keysym: special keys" {
108
    try testing.expectEqual(@as(?u64, 0xff0d), key_name_to_keysym("Return"));
109
    try testing.expectEqual(@as(?u64, 0xff0d), key_name_to_keysym("Enter"));
110
    try testing.expectEqual(@as(?u64, 0xff09), key_name_to_keysym("Tab"));
111
    try testing.expectEqual(@as(?u64, 0xff1b), key_name_to_keysym("Escape"));
112
}
113
114
test "key_name_to_keysym: lowercase letters" {
115
    try testing.expectEqual(@as(?u64, 'a'), key_name_to_keysym("a"));
116
    try testing.expectEqual(@as(?u64, 'z'), key_name_to_keysym("z"));
117
}
118
119
test "key_name_to_keysym: uppercase converts to lowercase" {
120
    try testing.expectEqual(@as(?u64, 'a'), key_name_to_keysym("A"));
121
    try testing.expectEqual(@as(?u64, 'z'), key_name_to_keysym("Z"));
122
}
123
124
test "key_name_to_keysym: numbers" {
125
    try testing.expectEqual(@as(?u64, '0'), key_name_to_keysym("0"));
126
    try testing.expectEqual(@as(?u64, '9'), key_name_to_keysym("9"));
127
}
128
129
test "key_name_to_keysym: unknown returns null" {
130
    try testing.expectEqual(@as(?u64, null), key_name_to_keysym("UnknownKey"));
131
    try testing.expectEqual(@as(?u64, null), key_name_to_keysym(""));
132
}
133
134
test "key_name_to_keysym: space variants" {
135
    try testing.expectEqual(@as(?u64, 0x0020), key_name_to_keysym("space"));
136
    try testing.expectEqual(@as(?u64, 0x0020), key_name_to_keysym("Space"));
137
}