-
Notifications
You must be signed in to change notification settings - Fork 5
/
keymap.zig
67 lines (57 loc) · 2.29 KB
/
keymap.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const std = @import("std");
const posix = std.posix;
const x = @import("x.zig");
pub fn send(sock: std.posix.socket_t, data: []const u8) !void {
const sent = try x.writeSock(sock, data, 0);
if (sent != data.len) {
std.log.err("send {} only sent {}\n", .{data.len, sent});
return error.DidNotSendAllData;
}
}
fn readSocket(sock: posix.socket_t, buffer: []u8) !usize {
return x.readSock(sock, buffer, 0);
}
pub const SocketReader = std.io.Reader(posix.socket_t, posix.RecvFromError, readSocket);
pub const Keymap = struct {
keycode_count: u8,
syms_per_code: u8,
syms: []u32,
pub fn deinit(self: Keymap, allocator: std.mem.Allocator) void {
allocator.free(self.syms);
}
};
// TODO: use a generic X connection rather than sock
// request the keymap from the server.
// this function sends a messages and expects a reply to that message so this must
// be done before registering for any asynchronouse events from the server.
pub fn request(allocator: std.mem.Allocator, sock: posix.socket_t, fixed: x.ConnectSetup.Fixed) !Keymap {
const keycode_count: u8 = fixed.max_keycode - fixed.min_keycode + 1;
{
var msg: [x.get_keyboard_mapping.len]u8 = undefined;
x.get_keyboard_mapping.serialize(&msg, fixed.min_keycode, keycode_count);
try send(sock, &msg);
}
var header: [32]u8 align(4) = undefined;
try x.readFull(SocketReader{ .context = sock }, &header);
{
const generic: *x.ServerMsg.Generic = @ptrCast(&header);
if (generic.kind != .reply) {
std.log.err("GetKeyboardMapping failed, expected 'reply' but got '{}': {}", .{
generic.kind,
generic,
});
return error.UnexpectedXServerReply;
}
}
const reply: *x.ServerMsg.GetKeyboardMapping = @ptrCast(&header);
const syms_len = x.readIntNative(u32, header[4..]);
std.debug.assert(@as(usize, reply.syms_per_code) * @as(usize, keycode_count) == syms_len);
const syms = try allocator.alloc(u32, syms_len);
errdefer allocator.free(syms);
try x.readFull(SocketReader{ .context = sock }, @as([*]u8, @ptrCast(syms.ptr))[0 .. syms_len * 4]);
return Keymap{
.keycode_count = keycode_count,
.syms_per_code = reply.syms_per_code,
.syms = syms,
};
}