// File: exrok[P]evdoublebind/./src/inspector.cc
// Function: poll_keyboard_events(Settings&, KeyboardList&)
int poll_keyboard_events(Settings &settings, KeyboardList &keyboards) {

    struct xkb_context *ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
    struct xkb_rule_names names = settings.xkb_names;
    struct xkb_keymap *keymap = xkb_keymap_new_from_names(ctx, &names,
                                       XKB_KEYMAP_COMPILE_NO_FLAGS);
    struct xkb_state *state = xkb_state_new(keymap);
    int epfd, ret;
    struct epoll_event evs[16];


    epfd = epoll_create1(0);
    if (epfd < 0) {
        fprintf(stderr, "Couldn't create epoll instance: %s\n",
                strerror(errno));
        return -errno;
    }

    for (int i =0; i < keyboards.len; i++) {
        struct epoll_event ev;
        memset(&ev, 0, sizeof(ev));
        ev.events = EPOLLIN;
        ev.data.ptr = keyboards.keyboards + i;
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, keyboards.keyboards[i].fd, &ev);
        if (ret) {
            ret = -errno;
            fprintf(stderr, "Couldn't add %s to epoll: %s\n",
                    keyboards.keyboards[i].name, strerror(errno));
            goto err_epoll;
        }
    }

    while (1) {
        ret = epoll_wait(epfd, evs, 16, -1);
        if (ret < 0) {
            if (errno == EINTR) continue;
            ret = -errno;
            fprintf(stderr, "Poll Error for events: %s\n",
                    strerror(errno));
            goto err_epoll;
        }
        for (int i = 0; i < ret; i++) {
            read_events(keymap, state, (Keyboard *)evs[i].data.ptr);
            // kbd = evs[i].data.ptr;
            // ret = read_keyboard(kbd);
            // if (ret) {
            //     goto err_epoll;
            // }
        }
    }

    close(epfd);
    return 0;

err_epoll:
    close(epfd);
    return ret;
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
xorl %edi, %edi
callq 0x3170
movq %rax, 0x148(%rsp)
movq 0x158(%rsp), %rsi
leaq 0x120(%rsp), %rdi
movl $0x28, %edx
callq 0x3190
movq 0x148(%rsp), %rdi
leaq 0x120(%rsp), %rsi
xorl %edx, %edx
callq 0x30e0
movq %rax, 0x118(%rsp)
movq 0x118(%rsp), %rdi
callq 0x3140
movq %rax, 0x110(%rsp)
xorl %edi, %edi
callq 0x3250
movl %eax, 0x10c(%rsp)
cmpl $0x0, 0x10c(%rsp)
jge 0x3d15
movq 0x4325(%rip), %rax      # 0x7ff8
movq (%rax), %rax
movq %rax, 0x20(%rsp)
callq 0x3040
movl (%rax), %edi
callq 0x3240
movq 0x20(%rsp), %rdi
movq %rax, %rdx
leaq 0x1ef4(%rip), %rsi      # 0x5bea
movb $0x0, %al
callq 0x3160
callq 0x3040
movq %rax, %rcx
xorl %eax, %eax
subl (%rcx), %eax
movl %eax, 0x164(%rsp)
jmp 0x3f0d
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
movq 0x150(%rsp), %rcx
cmpl 0x200(%rcx), %eax
jge 0x3e22
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
movl $0xc, %edx
callq 0x30d0
movl $0x1, 0x30(%rsp)
movq 0x150(%rsp), %rax
movslq 0x3c(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x34(%rsp)
movl 0x10c(%rsp), %edi
movq 0x150(%rsp), %rax
movslq 0x3c(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %edx
movl $0x1, %esi
leaq 0x30(%rsp), %rcx
callq 0x3120
movl %eax, 0x108(%rsp)
cmpl $0x0, 0x108(%rsp)
je 0x3e10
callq 0x3040
movq %rax, %rcx
xorl %eax, %eax
subl (%rcx), %eax
movl %eax, 0x108(%rsp)
movq 0x4239(%rip), %rax      # 0x7ff8
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x150(%rsp), %rax
movslq 0x3c(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x3040
movl (%rax), %edi
callq 0x3240
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rdx
movq %rax, %rcx
leaq 0x1e0a(%rip), %rsi      # 0x5c0e
movb $0x0, %al
callq 0x3160
jmp 0x3ef3
jmp 0x3e12
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x3d1d
jmp 0x3e24
movl 0x10c(%rsp), %edi
leaq 0x40(%rsp), %rsi
movl $0x10, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0x31d0
movl %eax, 0x108(%rsp)
cmpl $0x0, 0x108(%rsp)
jge 0x3ea2
callq 0x3040
cmpl $0x4, (%rax)
jne 0x3e5c
jmp 0x3e24
callq 0x3040
movq %rax, %rcx
xorl %eax, %eax
subl (%rcx), %eax
movl %eax, 0x108(%rsp)
movq 0x4182(%rip), %rax      # 0x7ff8
movq (%rax), %rax
movq %rax, 0x8(%rsp)
callq 0x3040
movl (%rax), %edi
callq 0x3240
movq 0x8(%rsp), %rdi
movq %rax, %rdx
leaq 0x1d93(%rip), %rsi      # 0x5c2c
movb $0x0, %al
callq 0x3160
jmp 0x3ef3
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x108(%rsp), %eax
jge 0x3eee
movq 0x118(%rsp), %rdi
movq 0x110(%rsp), %rsi
movslq 0x2c(%rsp), %rcx
leaq 0x40(%rsp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq 0x4(%rax), %rdx
callq 0x3a40
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x3eaa
jmp 0x3e24
movl 0x10c(%rsp), %edi
callq 0x3100
movl 0x108(%rsp), %eax
movl %eax, 0x164(%rsp)
movl 0x164(%rsp), %eax
addq $0x168, %rsp            # imm = 0x168
retq
nopl (%rax)