| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- #include "pocketpy/pocketpy.h"
- #include <stdlib.h>
- #if PY_SYS_PLATFORM == 0
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <conio.h>
- #elif PY_SYS_PLATFORM == 3 || PY_SYS_PLATFORM == 5
- #include <stdio.h>
- #include <unistd.h>
- #include <termios.h>
- #include <fcntl.h>
- #include <string.h>
- // 保存原始终端设置
- static struct termios orig_termios;
- static bool orig_termios_set;
- // 还原终端设置
- static void reset_terminal_mode() { tcsetattr(0, TCSANOW, &orig_termios); }
- // 设置终端为非阻塞模式
- static void set_conio_terminal_mode_if_needed() {
- if(orig_termios_set) return;
- struct termios new_termios;
- // 获取当前终端设置
- tcgetattr(0, &orig_termios);
- memcpy(&new_termios, &orig_termios, sizeof(new_termios));
- // 禁用缓冲和回显
- new_termios.c_lflag &= ~(ICANON | ECHO);
- tcsetattr(0, TCSANOW, &new_termios);
- atexit(reset_terminal_mode);
- orig_termios_set = true;
- }
- // 检查是否有按键按下
- int _kbhit() {
- set_conio_terminal_mode_if_needed();
- struct termios term;
- int oldf;
- int ch;
- int old_flags;
- // 获取终端设置
- tcgetattr(0, &term);
- oldf = term.c_lflag;
- term.c_lflag &= ~(ICANON | ECHO);
- tcsetattr(0, TCSANOW, &term);
- // 设置文件描述符为非阻塞
- old_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
- fcntl(STDIN_FILENO, F_SETFL, old_flags | O_NONBLOCK);
- // 检查是否有输入
- ch = getchar();
- // 还原文件描述符设置
- fcntl(STDIN_FILENO, F_SETFL, old_flags);
- // 还原终端设置
- term.c_lflag = oldf;
- tcsetattr(0, TCSANOW, &term);
- if(ch != EOF) {
- ungetc(ch, stdin);
- return 1;
- }
- return 0;
- }
- // 获取一个字符
- int _getch() {
- set_conio_terminal_mode_if_needed();
- int ch;
- struct termios oldt, newt;
- // 获取当前终端设置
- tcgetattr(STDIN_FILENO, &oldt);
- newt = oldt;
- // 禁用缓冲和回显
- newt.c_lflag &= ~(ICANON | ECHO);
- tcsetattr(STDIN_FILENO, TCSANOW, &newt);
- // 读取字符
- ch = getchar();
- // 还原终端设置
- tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
- return ch;
- }
- #endif
- #if PK_IS_DESKTOP_PLATFORM && PK_ENABLE_OS
- static bool conio_kbhit(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- int ret = _kbhit();
- py_newint(py_retval(), ret);
- return true;
- }
- static bool conio_getch(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- int ret = _getch();
- py_newint(py_retval(), ret);
- return true;
- }
- void pk__add_module_conio() {
- py_Ref mod = py_newmodule("conio");
- py_bindfunc(mod, "_kbhit", conio_kbhit);
- py_bindfunc(mod, "_getch", conio_getch);
- }
- #else
- void pk__add_module_conio() {}
- #endif
|