// File: /workspace/github_cpp_makefile_star2_O2/fgheng[P]keysound/src/KeyDetect.cc
// Function: key_detect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Audio*, Mixer*)
void key_detect(std::string str_event_id, Audio *audio, Mixer *mixer) {
    input_event ie;
    // int tid = std::stoi(event_id);

    int fd;
    fd_set fds;
    struct timeval tv;

    // 如果使用suid的话，不需要sleep即可正常读取/dev/input/event文件				If you use suid, you can read /dev/input/event files normally without using sleep
    // 如果使用input组的方式，那么需要加上sleep，否则新插入的键盘会读取失败			If you use the "input" group method, you need to add sleep, otherwise the newly inserted keyboard will fail to read
    // 不清楚是为什么，是因为文件创建的慢了？还是权限不够了？					Not sure why, is it because the file creation is slow? Still not enough permissions?
    // 也不是文件不存在的问题，我尝试判断文件是否存在，文件是存在的				It's not because the file doesn't exist, I tried to see if it does and it does in fact exist.
    // 那是因为权限没有跟上？尝试了一下确实是不可读，这是为什么呢？因为权限管理的延迟？		Is that because the permissions didn't carry over? After one  try, it becomes  unreadable. Why is this? Because
    // 使用open的阻塞方式 O_NONBLOCK 打开也不行							of the delay in rights management?
    // add_event_id(str_event_id);								Use O_NONBLOCK method when opening
    // while (event_id_exists(str_event_id) && access((input_file_header + str_event_id).c_str(), R_OK) == -1) {
        // usleep(100 * 1000);
        // std::cout << "判断是否有权限" << std::endl;
    // }
    // 经过搜索，我找到了原因，是因为程序读取太快，在udev正确设置权限之前就读取了		After searching, I found the reason, because the program reads too fast, it reads before udev sets the permissions correctly
    // 有两个解决方案，一个是等待一段时间，比如sleep(1)						There are two solutions, one is to wait for a period of time, such as with  sleep(1)
    // 第二个是使用inotify监控文件的权限更改							The second choice is to use "inotify" to monitor file permission changes
    sleep(1);
    fd = open((input_file_header + str_event_id).c_str(), O_RDONLY);

    if (fd == -1) {
        std::cout << "Error occured while attempting to open event file: " << input_file_header + str_event_id;
        std::cout << " you may not have access to the file " << std::endl;
        return;
    }

    // 成功运行，添加到key_detect_threads中		It has successfully run, add to key_detect_threads
    add_event_id(str_event_id);
    while(event_id_exists(str_event_id)) {
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;

        int ret = select(fd+1, &fds, NULL, NULL, &tv);

        if (ret < 0 ) continue;
        if (!(ret > 0 && FD_ISSET(fd, &fds))) continue;

        ssize_t num = read(fd, (void *)&ie, sizeof(struct input_event));

        if (num == -1 || num != sizeof(struct input_event)) continue;

        // 键盘事件	Keyboard events
        if (ie.type == EV_KEY) {
            switch (ie.value) {
                case KEY_PRESS:
                {
                    WAV_DATA wd = audio->get_wav_by_code(ie.code);
                    std::cout << " [" << ie.code << "] is pressed " << std::endl;
                    mixer->mix(wd.data, wd.len, wd.bits_per_sample);
                    break;
                }
                case KEY_RELEASE:
                {
                    // std::cout << "some key release" << std::endl;
                    break;
                }
                case KEY_REPEAT:
                {
                    // std::cout << "some key repeat" << std::endl;
                    break;
                }
                default: break;
            }
        }
    }

    if (fd>0) close(fd);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %rdx, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
movq %rdi, %r15
pushq $0x1
popq %rdi
callq 0x3250
leaq 0xcc53(%rip), %rsi      # 0x14bb8
leaq 0x30(%rsp), %r14
movq %r14, %rdi
movq %r15, %rdx
callq 0x7bc7
movq (%r14), %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x3230
movl %eax, %r13d
leaq 0x30(%rsp), %rdi
callq 0x3618
cmpl $-0x1, %r13d
je 0x811d
leaq 0x78(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x3410
movq %r14, %rdi
callq 0xb130
leaq 0x78(%rsp), %rdi
callq 0x3618
pushq $0x40
popq %rcx
movl %r13d, %eax
cltd
idivl %ecx
movslq %eax, %r12
shll $0x6, %eax
movl %r13d, %ecx
subl %eax, %ecx
pushq $0x1
popq %rbx
shlq %cl, %rbx
movq %r13, 0x8(%rsp)
leal 0x1(%r13), %ebp
leaq 0x98(%rsp), %r13
movq %r15, 0x10(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0x3410
movq %r13, %rdi
callq 0xb1a3
movl %eax, %r14d
movq %r13, %rdi
callq 0x3618
testb %r14b, %r14b
je 0x810d
xorl %eax, %eax
cmpq $0x10, %rax
je 0x8027
andq $0x0, 0xb8(%rsp,%rax,8)
incq %rax
jmp 0x8013
orq %rbx, 0xb8(%rsp,%r12,8)
andq $0x0, 0x50(%rsp)
movq $0x186a0, 0x58(%rsp)    # imm = 0x186A0
movl %ebp, %edi
leaq 0xb8(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
leaq 0x50(%rsp), %r8
callq 0x32f0
testl %eax, %eax
jle 0x7fea
testq %rbx, 0xb8(%rsp,%r12,8)
je 0x7fea
movq 0x8(%rsp), %rdi
leaq 0x60(%rsp), %rsi
pushq $0x18
popq %rdx
callq 0x3450
cmpq $0x18, %rax
jne 0x7fea
cmpw $0x1, 0x70(%rsp)
jne 0x7fea
cmpl $0x1, 0x74(%rsp)
jne 0x7fea
movzwl 0x72(%rsp), %r15d
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x6bb6
movq %rax, 0x28(%rsp)
movq %rdx, %r14
movq 0x9eff(%rip), %rdi      # 0x11fb8
leaq 0x4735(%rip), %rsi      # 0xc7f5
callq 0x3310
movq %rax, %rdi
movl %r15d, %esi
movq 0x10(%rsp), %r15
callq 0x3530
movq %rax, %rdi
leaq 0x4719(%rip), %rsi      # 0xc7f8
callq 0x3310
movq %rax, %rdi
callq 0x3180
movq %r14, %rax
shrq $0x20, %rax
movzwl %ax, %ecx
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
movl %r14d, %edx
callq 0x822a
jmp 0x7fea
movq 0x8(%rsp), %rdi
testl %edi, %edi
jle 0x817a
callq 0x35f0
jmp 0x817a
movq 0x9e94(%rip), %rdi      # 0x11fb8
leaq 0x4670(%rip), %rsi      # 0xc79b
callq 0x3310
movq %rax, %r14
leaq 0xca7e(%rip), %rsi      # 0x14bb8
movq %r15, %rdx
leaq 0x30(%rsp), %r15
movq %r15, %rdi
callq 0x7bc7
movq %r14, %rdi
movq %r15, %rsi
callq 0x32a0
leaq 0x30(%rsp), %rdi
callq 0x3618
movq 0x9e52(%rip), %rdi      # 0x11fb8
leaq 0x4662(%rip), %rsi      # 0xc7cf
callq 0x3310
movq %rax, %rdi
callq 0x3180
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x8198
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
jmp 0x81ad
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
jmp 0x81ad
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x3618
movq %rbx, %rdi
callq 0x3570
nop