// File: /workspace/github_cpp_makefile_star2_O1/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 $0x148, %rsp            # imm = 0x148
movq %rdx, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdi, %rbx
movl $0x1, %edi
callq 0x3290
leaq 0xcaa5(%rip), %rsi      # 0x15bd8
leaq 0x18(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
callq 0x8d90
movq (%r14), %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x3270
movl %eax, %r14d
leaq 0x28(%rsp), %r12
movq -0x10(%r12), %rdi
cmpq %r12, %rdi
je 0x916e
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x3390
cmpl $-0x1, %r14d
je 0x93d1
movq %r14, 0x8(%rsp)
leaq 0x88(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
leaq 0x78(%rsp), %r14
movq %r14, %rdi
callq 0x7ea6
movq %r14, %rdi
callq 0xceb8
movq 0x78(%rsp), %rdi
cmpq %r15, %rdi
movq 0x8(%rsp), %r14
je 0x91c7
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x3390
leal 0x3f(%r14), %eax
testl %r14d, %r14d
cmovnsl %r14d, %eax
movl %eax, %edx
andl $-0x40, %edx
movl %r14d, %ecx
subl %edx, %ecx
movl $0x1, %r15d
shlq %cl, %r15
sarl $0x6, %eax
movslq %eax, %rbp
leal 0x1(%r14), %eax
movl %eax, 0x14(%rsp)
leaq 0x58(%rsp), %r13
leaq 0x68(%rsp), %r14
movq %r14, 0x58(%rsp)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x7ea6
movq %r13, %rdi
callq 0xcf48
movl %eax, %r12d
movq 0x58(%rsp), %rdi
cmpq %r14, %rdi
je 0x9236
movq 0x68(%rsp), %rsi
incq %rsi
callq 0x3390
testb %r12b, %r12b
je 0x93ba
xorps %xmm0, %xmm0
movaps %xmm0, 0x130(%rsp)
movaps %xmm0, 0x120(%rsp)
movaps %xmm0, 0x110(%rsp)
movaps %xmm0, 0x100(%rsp)
movaps %xmm0, 0xf0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0xc0(%rsp)
orq %r15, 0xc0(%rsp,%rbp,8)
movq $0x0, 0x98(%rsp)
movq $0x186a0, 0xa0(%rsp) # imm = 0x186A0
movl 0x14(%rsp), %edi
leaq 0xc0(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
leaq 0x98(%rsp), %r8
callq 0x3330
testl %eax, %eax
jle 0x91f8
testq %r15, 0xc0(%rsp,%rbp,8)
je 0x91f8
movl $0x18, %edx
movq 0x8(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x34a0
cmpq $0x18, %rax
jne 0x91f8
cmpw $0x1, 0xb8(%rsp)
jne 0x91f8
cmpl $0x1, 0xbc(%rsp)
jne 0x91f8
movzwl 0xba(%rsp), %r14d
movq 0x38(%rsp), %rdi
movl %r14d, %esi
callq 0x7c72
movq %rax, 0x50(%rsp)
movq %rdx, 0x48(%rsp)
movl $0x2, %edx
movq 0x9c81(%rip), %r12      # 0x12fc0
movq %r12, %rdi
leaq 0x53e4(%rip), %rsi      # 0xe72d
callq 0x33d0
movq %r12, %rdi
movq %r14, %rsi
callq 0x3220
movq %rax, %r14
movl $0xd, %edx
movq %rax, %rdi
leaq 0x53c5(%rip), %rsi      # 0xe730
callq 0x33d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3340
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3230
movq 0x48(%rsp), %rdx
movq %rdx, %rax
shrq $0x20, %rax
movzwl %ax, %ecx
movq 0x40(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x9570
jmp 0x91f8
movq 0x8(%rsp), %rdi
testl %edi, %edi
jle 0x9464
callq 0x3640
jmp 0x9464
movq 0x9be8(%rip), %r14      # 0x12fc0
leaq 0x52f4(%rip), %rsi      # 0xe6d3
movl $0x33, %edx
movq %r14, %rdi
callq 0x33d0
leaq 0xc7e5(%rip), %rsi      # 0x15bd8
leaq 0x18(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rdx
callq 0x8d90
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r14, %rdi
callq 0x33d0
movq 0x18(%rsp), %rdi
cmpq %r12, %rdi
je 0x9429
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x3390
leaq 0x52d7(%rip), %rsi      # 0xe707
movl $0x25, %edx
movq %r14, %rdi
callq 0x33d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3340
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3230
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x18(%rsp), %rdi
cmpq %r12, %rdi
jne 0x94ad
jmp 0x94ce
movq %rax, %rbx
movq 0x78(%rsp), %rdi
cmpq %r15, %rdi
je 0x94ce
movq 0x88(%rsp), %rsi
jmp 0x94c6
movq %rax, %rbx
leaq 0x28(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x94ce
movq 0x28(%rsp), %rsi
jmp 0x94c6
movq %rax, %rbx
movq 0x58(%rsp), %rdi
cmpq %r14, %rdi
je 0x94ce
movq 0x68(%rsp), %rsi
incq %rsi
callq 0x3390
movq %rbx, %rdi
callq 0x35e0
nop