/* * process_keyboard_input() * * Description: * This runs for every keypress. It handles the input based on its scancode. * Regular characters are placed into the command buffer. Other key inputs such * as backspace, delete, enter, ctrl, alt, and arrow keys perform their * respective tasks. * * Inputs: * scancode: byte of data retrieved from keyboard * * Outputs: none */ void process_keyboard_input(uint8_t scancode) { uint8_t nextcode; uint32_t new_terminal; int32_t cursor_index = cursor_x[active_terminal]; int i; /* Store the datum received from the keyboard port. */ if ( 0 == (keyboardflag[active_terminal] & FLAG_CTRL) && ((scancode >= MAKE_1 && scancode <= MAKE_EQUALS) || (scancode >= MAKE_Q && scancode <= MAKE_R_SQUARE_BRACKET) || (scancode >= MAKE_A && scancode <= MAKE_ACCENT) || (scancode >= MAKE_BACKSLASH && scancode <= MAKE_SLASH) || scancode == MAKE_SPACE) ) { /* (Stop placing characters in the command_buffer if * command_length is big.) */ if (command_length[active_terminal] + 1 < TERMINAL_BUFFER_MAX_SIZE) { /* Put the character into the buffer (shift data if necessary). */ place_character_at_index(scancode, cursor_x[active_terminal]); } } else if (scancode == MAKE_ENTER) { /* Remove the lock on terminal reading. */ allow_terminal_read[active_terminal] = 1; } else if (scancode == MAKE_BKSP) { /* Backspace, shifting data if necessary. */ if (cursor_index > 0 ) { cursor_index--; while ( cursor_index < command_length[active_terminal]) { command_buffer[active_terminal][cursor_index] = command_buffer[active_terminal][cursor_index+1]; cursor_index++; } command_length[active_terminal]--; cursor_x[active_terminal]--; } } else if (scancode == MAKE_DELETE) { /* Delete, shifting data if necessary. */ if (cursor_index >= 0 && cursor_index < command_length[active_terminal]) { while (cursor_index < command_length[active_terminal]) { command_buffer[active_terminal][cursor_index] = command_buffer[active_terminal][cursor_index+1]; cursor_index++; } command_length[active_terminal]--; } } else if (scancode == MAKE_CAPS) { /* Change the keyboard flags for +/- CAPSLOCK */ keyboardflag[active_terminal] ^= FLAG_CAPS; } else if (scancode == MAKE_L_SHFT || scancode == MAKE_R_SHFT) /* Shift down */ { /* Change the keyboard flags for + SHIFT */ keyboardflag[active_terminal] |= FLAG_SHIFT; } else if (scancode == BREAK_L_SHFT || scancode == BREAK_R_SHFT) /* Shift up */ { /* Change the keyboard flags for - SHIFT */ keyboardflag[active_terminal] &= ~FLAG_SHIFT; } else if (scancode == MAKE_L_CTRL) /* Ctrl down */ { /* Change the keyboard flags for + CTRL */ keyboardflag[active_terminal] |= FLAG_CTRL; } else if (scancode == BREAK_L_CTRL) /* Ctrl up */ { /* Change the keyboard flags for - CTRL */ keyboardflag[active_terminal] &= ~FLAG_CTRL; } else if (scancode == MAKE_L_ALT) /* Alt down */ { /* Change the keyboard flags for + ALT */ keyboardflag[active_terminal] |= 0x08; } else if (scancode == BREAK_L_ALT) /* Alt up */ { /* Change the keyboard flags for - ALT */ keyboardflag[active_terminal] &= ~0x8; } else if ( scancode >= MAKE_F1 && scancode <= MAKE_F3){ if(keyboardflag[active_terminal] & 0x8){ new_terminal = (scancode & 0x7) - 3; if( new_terminal != active_terminal){ active_terminal = new_terminal; set_active_term(new_terminal); load_video_memory(active_terminal); } } } else if (scancode == EXTRAS) /* Directional and RCTRL */ { /* Get next keyboard input */ nextcode = inb(KEYBOARD_PORT); /* Move cursor based on arrow key input. */ if (nextcode == MAKE_L_ARROW && cursor_x[active_terminal] > 0) { cursor_x[active_terminal]--; } else if (nextcode == MAKE_R_ARROW && cursor_x[active_terminal] < command_length[active_terminal] ) { cursor_x[active_terminal]++; } else if (nextcode == MAKE_L_CTRL) { /* Change the keyboard flags for + CTRL */ keyboardflag[active_terminal] |= FLAG_CTRL; } else if (nextcode == BREAK_L_CTRL) { /* Change the keyboard flags for - CTRL */ keyboardflag[active_terminal] &= ~FLAG_CTRL; } } else if (keyboardflag[active_terminal] & FLAG_CTRL) /* CTRL + L */ { /* Implement screen clear with CTRL + L input. */ if (scancode == MAKE_L){ for (i=0; i < command_length[active_terminal]; i++) { command_buffer[active_terminal][i] = NULL; } command_length[active_terminal] = 0; cursor_x[active_terminal] = 0; allow_terminal_read[active_terminal] = 1; clear_the_screen(); keyboardflag[active_terminal] &= ~FLAG_CTRL; } } else { /* unknown scancode: do nothing */ } update_cursor(cursor_x[active_terminal]); }
/* * playit: * Play a given game, handling all the curses commands from * the driver. */ void playit() { int ch; int y, x; u_int32_t version; if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) { bad_con(); /* NOTREACHED */ } if (ntohl(version) != (unsigned long)HUNT_VERSION) { bad_ver(); /* NOTREACHED */ } errno = 0; # ifdef OTTO Otto_count = 0; # endif nchar_send = MAX_SEND; while ((ch = GETCHR()) != EOF) { # ifdef DEBUG fputc(ch, stderr); # endif switch (ch & 0377) { case MOVE: y = GETCHR(); x = GETCHR(); # ifdef USE_CURSES move(y, x); # else mvcur(cur_row, cur_col, y, x); cur_row = y; cur_col = x; # endif break; case ADDCH: ch = GETCHR(); # ifdef OTTO switch (ch) { case '<': case '>': case '^': case 'v': otto_face = ch; # ifdef USE_CURSES getyx(stdscr, otto_y, otto_x); # else otto_y = cur_row; otto_x = cur_col; # endif break; } # endif put_ch(ch); break; case CLRTOEOL: clear_eol(); break; case CLEAR: clear_the_screen(); break; case REFRESH: refresh(); break; case REDRAW: redraw_screen(); refresh(); break; case ENDWIN: refresh(); if ((ch = GETCHR()) == LAST_PLAYER) Last_player = TRUE; ch = EOF; goto out; case BELL: beep(); break; case READY: refresh(); if (nchar_send < 0) # if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44) tcflush(STDIN, TCIFLUSH); # else # ifndef TCFLSH (void) ioctl(STDIN, TIOCFLUSH, &in); # else (void) ioctl(STDIN, TCFLSH, 0); # endif # endif nchar_send = MAX_SEND; # ifndef OTTO (void) GETCHR(); # else Otto_count -= (GETCHR() & 0xff); if (!Am_monitor) { # ifdef DEBUG fputc('0' + Otto_count, stderr); # endif if (Otto_count == 0 && Otto_mode) otto(otto_y, otto_x, otto_face); } # endif break; default: # ifdef OTTO switch (ch) { case '<': case '>': case '^': case 'v': otto_face = ch; # ifdef USE_CURSES getyx(stdscr, otto_y, otto_x); # else otto_y = cur_row; otto_x = cur_col; # endif break; } # endif put_ch(ch); break; } } out: (void) close(Socket); }
static void find_driver(void) { u_short msg; const struct sockaddr_storage *host; socklen_t hostlen; unsigned num; int i, c; msg = C_PLAYER; #ifdef MONITOR if (Am_monitor) { msg = C_MONITOR; } #endif serverlist_query(msg); num = serverlist_num(); if (num == 0) { start_driver(); sleep(2); /* try again */ serverlist_query(msg); num = serverlist_num(); if (num == 0) { /* give up */ return; } } if (num == 1) { host = serverlist_gethost(0, &hostlen); } else { clear_the_screen(); move(1, 0); addstr("Pick one:"); for (i = 0; i < HEIGHT - 4 && i < (int)num; i++) { move(3 + i, 0); host = serverlist_gethost(i, &hostlen); printw("%8c %.64s", 'a' + i, lookuphost(host, hostlen)); } move(4 + i, 0); addstr("Enter letter: "); refresh(); while (1) { c = getchar(); if (c == EOF) { leavex(1, "EOF on stdin"); } if (islower((unsigned char)c) && c - 'a' < i) { break; } beep(); refresh(); } clear_the_screen(); host = serverlist_gethost(c - 'a', &hostlen); } /* XXX fix this (won't work in ipv6) */ assert(hostlen == sizeof(Daemon)); memcpy(&Daemon, host, sizeof(Daemon)); }
/* * playit: * Play a given game, handling all the curses commands from * the driver. */ void playit(void) { int ch; int y, x; uint32_t version; ssize_t result; result = read(huntsocket, &version, sizeof(version)); if (result != (ssize_t)sizeof(version)) { bad_con(); /* NOTREACHED */ } if (ntohl(version) != (uint32_t)HUNT_VERSION) { bad_ver(); /* NOTREACHED */ } errno = 0; #ifdef OTTO Otto_count = 0; #endif nchar_send = MAX_SEND; while ((ch = GETCHR()) != EOF) { #ifdef DEBUG fputc(ch, stderr); #endif switch (ch & 0377) { case MOVE: y = GETCHR(); x = GETCHR(); move(y, x); break; case ADDCH: ch = GETCHR(); #ifdef OTTO switch (ch) { case '<': case '>': case '^': case 'v': otto_face = ch; getyx(stdscr, otto_y, otto_x); break; } #endif addch(ch); break; case CLRTOEOL: clrtoeol(); break; case CLEAR: clear_the_screen(); break; case REFRESH: refresh(); break; case REDRAW: redraw_screen(); refresh(); break; case ENDWIN: refresh(); if ((ch = GETCHR()) == LAST_PLAYER) Last_player = true; ch = EOF; goto out; case BELL: beep(); break; case READY: refresh(); if (nchar_send < 0) tcflush(STDIN_FILENO, TCIFLUSH); nchar_send = MAX_SEND; #ifndef OTTO (void) GETCHR(); #else Otto_count -= (GETCHR() & 0xff); if (!Am_monitor) { #ifdef DEBUG fputc('0' + Otto_count, stderr); #endif if (Otto_count == 0 && Otto_mode) otto(otto_y, otto_x, otto_face); } #endif break; default: #ifdef OTTO switch (ch) { case '<': case '>': case '^': case 'v': otto_face = ch; getyx(stdscr, otto_y, otto_x); break; } #endif addch(ch); break; } } out: (void) close(huntsocket); }
/* * main: * Main program for local process */ int main(int ac, char **av) { char *term; int c; int enter_status; bool Query_driver = false; bool Show_scores = false; enter_status = env_init(Q_CLOAK); while ((c = getopt(ac, av, "Sbcfh:l:mn:op:qst:w:")) != -1) { switch (c) { case 'l': /* rsh compatibility */ case 'n': (void) strncpy(name, optarg, sizeof(name)); break; case 't': team = *optarg; if (!isdigit((unsigned char)team)) { warnx("Team names must be numeric"); team = ' '; } break; case 'o': #ifndef OTTO warnx("The -o flag is reserved for future use."); goto usage; #else Otto_mode = true; break; #endif case 'm': #ifdef MONITOR Am_monitor = true; #else warnx("The monitor was not compiled in."); #endif break; #ifdef INTERNET case 'S': Show_scores = true; break; case 'q': /* query whether hunt is running */ Query_driver = true; break; case 'w': Send_message = optarg; break; case 'h': contacthost = optarg; break; case 'p': contactportstr = optarg; contactport = atoi(contactportstr); break; #else case 'S': case 'q': case 'w': case 'h': case 'p': wanrx("Need TCP/IP for S, q, w, h, and p options."); break; #endif case 'c': enter_status = Q_CLOAK; break; case 'f': #ifdef FLY enter_status = Q_FLY; #else warnx("The flying code was not compiled in."); #endif break; case 's': enter_status = Q_SCAN; break; case 'b': no_beep = !no_beep; break; default: usage: fputs( "usage:\thunt [-qmcsfS] [-n name] [-t team] [-p port] [-w message] [host]\n", stderr); exit(1); } } #ifdef INTERNET if (optind + 1 < ac) goto usage; else if (optind + 1 == ac) contacthost = av[ac - 1]; #else if (optind < ac) goto usage; #endif #ifdef INTERNET serverlist_setup(contacthost, contactport); if (Show_scores) { const struct sockaddr_storage *host; socklen_t hostlen; u_short msg = C_SCORES; unsigned i; serverlist_query(msg); for (i = 0; i < serverlist_num(); i++) { host = serverlist_gethost(i, &hostlen); dump_scores(host, hostlen); } exit(0); } if (Query_driver) { const struct sockaddr_storage *host; socklen_t hostlen; u_short msg = C_MESSAGE; u_short num_players; unsigned i; serverlist_query(msg); for (i = 0; i < serverlist_num(); i++) { host = serverlist_gethost(i, &hostlen); num_players = ntohs(serverlist_getresponse(i)); printf("%d player%s hunting on %s!\n", num_players, (num_players == 1) ? "" : "s", lookuphost(host, hostlen)); } exit(0); } #endif #ifdef OTTO if (Otto_mode) (void) strncpy(name, "otto", sizeof(name)); else #endif fill_in_blanks(); (void) fflush(stdout); if (!isatty(0) || (term = getenv("TERM")) == NULL) errx(1, "no terminal type"); if (!initscr()) errx(0, "couldn't initialize screen"); (void) noecho(); (void) cbreak(); in_visual = true; if (LINES < SCREEN_HEIGHT || COLS < SCREEN_WIDTH) leavex(1, "Need a larger window"); clear_the_screen(); (void) signal(SIGINT, intr); (void) signal(SIGTERM, sigterm); (void) signal(SIGUSR1, sigusr1); (void) signal(SIGPIPE, SIG_IGN); for (;;) { #ifdef INTERNET find_driver(); if (Daemon.sin_port == 0) leavex(1, "Game not found, try again"); jump_in: do { int option; huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0); if (huntsocket < 0) err(1, "socket"); option = 1; if (setsockopt(huntsocket, SOL_SOCKET, SO_USELOOPBACK, &option, sizeof option) < 0) warn("setsockopt loopback"); errno = 0; if (connect(huntsocket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) { if (errno != ECONNREFUSED) { leave(1, "connect"); } } else break; sleep(1); } while (close(huntsocket) == 0); #else /* !INTERNET */ /* * set up a socket */ if ((huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) err(1, "socket"); /* * attempt to connect the socket to a name; if it fails that * usually means that the driver isn't running, so we start * up the driver. */ Daemon.sun_family = SOCK_FAMILY; (void) strcpy(Daemon.sun_path, huntsockpath); if (connect(huntsocket, &Daemon, DAEMON_SIZE) < 0) { if (errno != ENOENT) { leavex(1, "connect2"); } start_driver(); do { (void) close(huntsocket); if ((huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) err(1, "socket"); sleep(2); } while (connect(huntsocket, &Daemon, DAEMON_SIZE) < 0); } #endif do_connect(name, sizeof(name), team, enter_status); #ifdef INTERNET if (Send_message != NULL) { do_message(); if (enter_status == Q_MESSAGE) break; Send_message = NULL; /* don't continue as that will call find_driver */ goto jump_in; } #endif playit(); if ((enter_status = quit(enter_status)) == Q_QUIT) break; } leavex(0, NULL); /* NOTREACHED */ return(0); }