int tty_read(struct inode* inode, void* ptr, off_t pos, size_t len) { if(unlikely(!inode || !ptr)) { errno = EINVAL; return -1; } if(unlikely(!inode->userdata)) { errno = EINVAL; return -1; } if(unlikely(!len)) return 0; struct tty_context* tio = (struct tty_context*) inode->userdata; uint8_t* buf = (uint8_t*) ptr; int p = 0; if(tio->pgrp != current_task->pgid) sys_exit((1 << 31) | W_STOPCODE(SIGTTIN)); int fd = sys_open(TTY_DEFAULT_INPUT_DEVICE, O_RDONLY, 0); if(fd < 0) { errno = EIO; return -1; } if(fifo_available(&tio->in)) { char tmp[BUFSIZ]; for(int j = 0; (j = fifo_read(&tio->in, tmp, sizeof(tmp))) > 0;) fifo_write(&tio->uin, tmp, j); } while(p < len) { uint8_t ch; if(fifo_available(&tio->uin)) fifo_read(&tio->uin, &ch, sizeof(ch)); else ch = process_keyboard(inode, tio, fd, &p); switch(ch) { case 0: continue; case '\b': case '\x7f': if(tio->ios.c_lflag & ICANON) { if(p > 0) { fifo_peek(&tio->in, 1); p--; if(tio->ios.c_lflag & ECHOE) ch = '\b'; else ch = '\x7f'; if(tio->ios.c_lflag & ECHO) tty_output_write(inode, &ch, 0, 1); } continue; } /* No processing */ ch = '\b'; break; default: break; } if(unlikely(ch < 32)) { for(int i = 0; i < NCCS; i++) { if(ch != tio->ios.c_cc[i]) continue; fifo_write(&tio->in, &ch, 1); p++; ch = 0; break; } if(unlikely(!ch)) continue; } if(!(tio->ios.c_iflag & IGNCR)) { if(ch == '\n') break; } char utf8[UTF8_MAX_LENGTH]; size_t utf8len = ucs2_to_utf8((int32_t) ch, utf8); fifo_write(&tio->in, utf8, utf8len); p += utf8len; if(tio->ios.c_lflag & ECHO) tty_output_write(inode, utf8, 0, utf8len); } if(p < len) { if(!(tio->ios.c_iflag & IGNCR)) { char ch = '\n'; fifo_write(&tio->in, &ch, 1); p++; if((tio->ios.c_lflag & ECHO) || (tio->ios.c_lflag & ICANON && tio->ios.c_lflag & ECHONL)) tty_output_write(inode, &ch, 0, 1); } } else p = len; if(fifo_available(&tio->in)) fifo_read(&tio->in, buf, p); sys_close(fd); return p; }
/****** Handle Input From Keyboard ******/ void DMG_GamePad::handle_input(SDL_Event &event) { //Key Presses if(event.type == SDL_KEYDOWN) { pad = event.key.keysym.sym; process_keyboard(pad, true); } //Key Releases else if(event.type == SDL_KEYUP) { pad = event.key.keysym.sym; process_keyboard(pad, false); } //Joystick Button Presses else if(event.type == SDL_JOYBUTTONDOWN) { pad = 100 + event.jbutton.button; process_joystick(pad, true); } //Joystick Button Releases else if(event.type == SDL_JOYBUTTONUP) { pad = 100 + event.jbutton.button; process_joystick(pad, false); } //Joystick axes else if(event.type == SDL_JOYAXISMOTION) { pad = 200 + (event.jaxis.axis * 2); int axis_pos = event.jaxis.value; if(axis_pos > 0) { pad++; } else { axis_pos *= -1; } if(axis_pos > config::dead_zone) { process_joystick(pad, true); } else { process_joystick(pad, false); } } //Joystick hats else if(event.type == SDL_JOYHATMOTION) { pad = 300; pad += event.jhat.hat * 4; switch(event.jhat.value) { case SDL_HAT_LEFT: process_joystick(pad, true); process_joystick(pad+2, false); break; case SDL_HAT_LEFTUP: process_joystick(pad, true); process_joystick(pad+2, true); break; case SDL_HAT_LEFTDOWN: process_joystick(pad, true); process_joystick(pad+3, true); break; case SDL_HAT_RIGHT: process_joystick(pad+1, true); process_joystick(pad+2, false); break; case SDL_HAT_RIGHTUP: process_joystick(pad+1, true); process_joystick(pad+2, true); break; case SDL_HAT_RIGHTDOWN: process_joystick(pad+1, true); process_joystick(pad+3, true); break; case SDL_HAT_UP: process_joystick(pad+2, true); process_joystick(pad, false); break; case SDL_HAT_DOWN: process_joystick(pad+3, true); process_joystick(pad, false); break; case SDL_HAT_CENTERED: process_joystick(pad, false); process_joystick(pad+2, false); break; } } }