/* * The main terminal loop: * - If there are characters received send them * to the screen via the appropriate translate function. */ int do_terminal(void) { char buf[128]; int buf_offset = 0; int c; int x; int blen; int zauto = 0; static const char zsig[] = "**\030B00"; int zpos = 0; const char *s; dirflush = 0; WIN *error_on_open_window = NULL; dirty_goto: /* Show off or online time */ update_status_time(); /* If the status line was shown temporarily, delete it again. */ if (tempst) { tempst = 0; mc_wclose(st, 1); st = NULL; } /* Auto Zmodem? */ if (P_PAUTO[0] >= 'A' && P_PAUTO[0] <= 'Z') zauto = P_PAUTO[0]; /* Set the terminal modes */ setcbreak(2); /* Raw, no echo */ keyboard(KSTART, 0); /* Main loop */ while (1) { /* See if window size changed */ if (size_changed) { size_changed = 0; wrapln = us->wrap; /* I got the resize code going again! Yeah! */ mc_wclose(us, 0); us = NULL; if (st) mc_wclose(st, 0); st = NULL; mc_wclose(stdwin, 0); if (win_init(tfcolor, tbcolor, XA_NORMAL) < 0) leave(_("Could not re-initialize window system.")); /* Set the terminal modes */ setcbreak(2); /* Raw, no echo */ init_emul(terminal, 0); } /* Update the timer. */ timer_update(); /* check if device is ok, if not, try to open it */ if (!get_device_status(portfd_connected)) { /* Ok, it's gone, most probably someone unplugged the USB-serial, we * need to free the FD so that a replug can get the same device * filename, open it again and be back */ int reopen = portfd == -1; close(portfd); lockfile_remove(); portfd = -1; if (open_term(reopen, reopen, 1) < 0) { if (!error_on_open_window) error_on_open_window = mc_tell(_("Cannot open %s!"), dial_tty); } else { if (error_on_open_window) { mc_wclose(error_on_open_window, 1); error_on_open_window = NULL; } } } /* Check for I/O or timer. */ x = check_io(portfd_connected, 0, 1000, buf + buf_offset, sizeof(buf) - buf_offset, &blen); blen += buf_offset; buf_offset = 0; /* Data from the modem to the screen. */ if ((x & 1) == 1) { char obuf[sizeof(buf)]; char *ptr; if (using_iconv()) { char *otmp = obuf; size_t output_len = sizeof(obuf); size_t input_len = blen; ptr = buf; do_iconv(&ptr, &input_len, &otmp, &output_len); // something happened at all? if (output_len < sizeof(obuf)) { if (input_len) { // something remained, we need to adapt buf accordingly memmove(buf, ptr, input_len); buf_offset = input_len; } blen = sizeof(obuf) - output_len; ptr = obuf; } else ptr = buf; } else { ptr = buf; } while (blen-- > 0) { /* Auto zmodem detect */ if (zauto) { if (zsig[zpos] == *ptr) zpos++; else zpos = 0; } if (P_PARITY[0] == 'M' || P_PARITY[0] == 'S') *ptr &= 0x7f; if (display_hex) { unsigned char c = *ptr++; unsigned char u = c >> 4; c &= 0xf; vt_out(u > 9 ? 'a' + (u - 10) : '0' + u); vt_out(c > 9 ? 'a' + (c - 10) : '0' + c); vt_out(' '); } else vt_out(*ptr++); if (zauto && zsig[zpos] == 0) { dirflush = 1; keyboard(KSTOP, 0); updown('D', zauto - 'A'); dirflush = 0; zpos = 0; blen = 0; goto dirty_goto; } } mc_wflush(); }
/* * Read a character from the keyboard. * Handle special characters too! */ int wxgetch(void) { int f, g; int match = 1; int len; char c; static unsigned char mem[8]; static int leftmem = 0; static int init = 0; int nfound = 0; int start_match; #if VT_KLUDGE char temp[8]; #endif struct timeval timeout; fd_set readfds; if (init == 0) { _initkeys(); init++; erasechar = setcbreak(3); } /* Some sequence still in memory ? */ if (leftmem > 0) { leftmem--; if (leftmem == 0) pendingkeys = 0; if (pendingkeys == 0 && keys_in_buf == 0) io_pending = 0; return mem[leftmem]; } gotalrm = 0; pendingkeys = 0; for (len = 1; len < 8 && match; len++) { #if KEY_KLUDGE if (len > 1 && keys_in_buf == 0) #else if (len > 1) #endif { timeout.tv_sec = 0; timeout.tv_usec = 400000; /* 400 ms */ FD_ZERO(&readfds); FD_SET(0, &readfds); if (!(nfound = select(1, &readfds, NULL, NULL, &timeout))) break; } #if KEY_KLUDGE while ((nfound = cread(&c)) < 0 && (errno == EINTR && !gotalrm)) ; #else while ((nfound = read(0, &c, 1)) < 0 && (errno == EINTR && !gotalrm)) ; #endif if (nfound < 1) return EOF; if (len == 1) { /* Enter and erase have precedence over anything else */ if (c == '\n') return c; if (c == erasechar) return K_ERA; } #if KEY_KLUDGE /* Return single characters immideately */ if (isconsole && nfound == 1 && len == 1) return c; /* Another hack - detect the Meta Key. */ if (isconsole && nfound == 2 && len == 1 && c == 27 && escape == 27) { cread(&c); return c + K_META; } #endif mem[len - 1] = c; match = 0; #if VT_KLUDGE /* Oh boy. Stupid vt100 2 mode keyboard. */ strncpy(temp, mem, len); if (len > 1 && temp[0] == 27) { if (temp[1] == '[') temp[1] = 'O'; else if (temp[1] == 'O') temp[1] = '['; } /* We now have an alternate string to check. */ #endif start_match = 0; for (f = 0; f < NUM_KEYS; f++) { #if VT_KLUDGE if (_keys[f].len >= len && (strncmp(_keys[f].cap, (char *)mem, len) == 0 || strncmp(_keys[f].cap, (char *)temp, len) == 0)) #else if (_keys[f].len >= len && strncmp(_keys[f].cap, (char *)mem, len) == 0) #endif { match++; if (_keys[f].len == len) { return f + KEY_OFFS; } } /* Does it match on first two chars? */ if (_keys[f].len > 1 && len == 2 && strncmp(_keys[f].cap, (char *)mem, 2) == 0) start_match++; } #if KEY_KLUDGE if (!isconsole) #endif #ifndef _MINIX /* Minix doesn't have ESC-c meta mode */ /* See if this _might_ be a meta-key. */ if (escape == 27 && !start_match && len == 2 && mem[0] == 27) return c + K_META; #endif } /* No match. in len we have the number of characters + 1 */ len--; /* for convenience */ if (len == 1) return mem[0]; /* Remember there are more keys waiting in the buffer */ pendingkeys++; io_pending++; /* Reverse the "mem" array */ for (f = 0; f < len / 2; f++) { g = mem[f]; mem[f] = mem[len - f - 1]; mem[len - f - 1] = g; } leftmem = len - 1; return mem[leftmem]; }
int main() { printf("\033[?25l"); // Hide the cursor d_clear(0); int x=40<<3; // We store the upscaled coordinates here, divide this by 4 to get real screen coordinates int y=10<<3; int dx=4; // Direction on x axis, upscaled coordinate compatible value int dy=1; // Direction on y axis, upscaled coordinate compatible value int oldx; // Screen coordinate for erasing the ball int oldy; int newx; // Used for converting back to the "screen" coordinates before checking wall hits and paddle hits int newy; int p1=10; // Paddle 1's y coordinate - this is a screen coordinate int p2=10; #define pw 5 int p1score=0; int p2score=0; d_vline( 1, p1, p1+pw, 6); d_vline(78, p2, p2+pw, 6); int simpletimer=6; setcbreak(); int ch=-1; while (ch==-1 || ch!='q') { usleep(3000); ch=getch(); if (ch!=-1) { // Handles for the first paddle if (ch=='w' && p1>0) { d_putpixel(1, p1+pw, 0); --p1; d_putpixel(1, p1, 6); } if (ch=='s' && p1+pw<23) { d_putpixel(1, p1, 0); ++p1; d_putpixel(1, p1+pw, 6); } // Handles for the second paddle if (ch=='o' && p2>0) { d_putpixel(78, p2+pw, 0); --p2; d_putpixel(78, p2, 6); } if (ch=='l' && p2+pw<23) { d_putpixel(78, p2, 0); ++p2; d_putpixel(78, p2+pw, 6); } } --simpletimer; if (simpletimer<=0) { simpletimer=6; oldx=x>>3; oldy=y>>3; newx=(x+dx)>>3; // Now we can check screen objects against these for collision newy=(y+dy)>>3; if (newx==1 && newy>=p1 && newy<=p1+pw) dx*=-1; // Check if first paddle would be hit, if it is, reverse the x axis movement direction if (newx==78 && newy>=p2 && newy<=p2+pw) dx*=-1; // Check if second paddle... if (newy>23 || newy<0) dy*=-1; // If the upper or lower border would be crossed by this move, reverse the y axis movement if (newx<0 || newx>79) {// The ball went out on one side, place it on the center of the loser's paddle and let it fly d_goto(30,12); // Prepare the drawing cursor for text output at this position if (newx<40) {// The ball was on the left side when it exited the playable area, increment player 2's score, and put the ball on player 1's paddle ++p2score; newx=2; newy=p1+(pw/2); printf("Player 2 scores!"); } else { // Otherwise it was on the right side, increment player 1 score, put ball on player 2's paddle ++p1score; newx=77; newy=p2+(pw/2); printf("Player 1 scores!"); } dx*=-1; // Remember that the ball was headed outwards the last time we saw it, so we have to switch the horizontal direction x=newx<<3; // And scale up the screen coordinates for later use y=newy<<3; // Wait for a bit then erase the text d_goto(0,0); d_flush(); usleep(1000000); d_goto(30,12); printf(" "); d_goto(0,0); d_flush(); } x+=dx; y+=dy; // This is the movement d_putpixel(oldx, oldy, 0); d_putpixel(x>>3, y>>3, 3); // Remember, x and y stores upscaled coordinates, so we have to divide them by 4 for drawing [also remember that a bit shift to the right by 3 equals to that divide] } d_goto(10,0); printf("%i", p1score); d_goto(50,0); printf("%i", p2score); d_goto(0,0); d_flush(); }
/* * Main program of keyserv. */ int main(int argc, char **argv) { int c; char ch; int f, fun; int stopped = 0; if (argc < 2 || (parent = atoi(argv[1])) == 0) { printf("Usage: %s <parent>\n", *argv); exit(1); } /* Initialize signal handlers */ /* signal(SIGHUP, SIG_IGN); */ signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); #endif signal(HELLO, handler); /* Set up escape sequence table */ escseq = st_vtesc; /* Cbreak, no echo (minicom itself sets to raw if needed) */ setcbreak(1); if ((fun = setjmp(mainloop)) != 0) { switch (fun) { /* We come here after minicom has told us something */ case KVT100: /* VT100 keyboard */ mode = EVT100; escseq = st_vtesc; break; case KANSI: /* ANSI keyboard */ mode = EANSI; escseq = ansiesc; break; case KKPST: /* Keypad in standard mode, not used */ keypadmode = NORMAL; break; case KKPAPP: /* Keypad in applications mode, not used */ keypadmode = APPL; break; case KCURST: /* Standard cursor keys */ cursormode = NORMAL; if (mode == EVT100) escseq = st_vtesc; break; case KCURAPP: /* cursor keys in applications mode */ cursormode = APPL; if (mode == EVT100) escseq = app_vtesc; break; case KSTOP: /* Sleep until further notice */ stopped = 1; break; case KSIGIO: /* Wait for keypress and tell parent */ kill(parent, ACK); f = read(0, &ch, 1); if (f == 1) { write(to_minicom, &ch, 1); kill(parent, HELLO); } break; case KSTART: /* Restart when stopped */ stopped = 0; break; case KSETBS: /* Set code that BS key sends */ bs_code = argument; break; case KSETESC: /* Set escape character */ esc_char = argument; break; default: break; } if (fun != KSIGIO) kill(parent, ACK); } /* Wait if stopped */ if (stopped) pause(); /* Main loop: read keyboard, send to modem */ while (1) { c = wxgetch(); if (c > 256 && c < 256 + NUM_KEYS) { sendstr(escseq[c - 256]); } if (c < 256) { if (c == K_ERA) c = bs_code; ch = c; /* Test for escape characters */ if (c == esc_char || (esc_char == 128 && c > 128)) { /* If we typed too fast, and the escape sequence * was not that of a function key, the next key * is already in the buffer. */ if (c == esc_char && pendingkeys > 0) { ch = wxgetch(); } write(to_minicom, &ch, 1); kill(parent, HELLO); } else { write(1, &ch, 1); } } } return 0; }
/* * Run an external script. * ask = 1 if first ask for confirmation. * s = scriptname, l=loginname, p=password. */ void runscript(int ask, const char *s, const char *l, const char *p) { int status; int n, i; int pipefd[2]; char buf[81]; char scr_lines[5]; char cmdline[128]; struct pollfd fds[2]; char *translated_cmdline; char *ptr; WIN *w; int done = 0; char *msg = _("Same as last"); char *username = _(" A - Username :"******" B - Password :"******" C - Name of script :"), *question = _("Change which setting? (Return to run, ESC to stop)"); if (ask) { w = mc_wopen(10, 5, 70, 10, BDOUBLE, stdattr, mfcolor, mbcolor, 0, 0, 1); mc_wtitle(w, TMID, _("Run a script")); mc_wputs(w, "\n"); mc_wprintf(w, "%s %s\n", username, scr_user[0] ? msg : ""); mc_wprintf(w, "%s %s\n", password, scr_passwd[0] ? msg : ""); mc_wprintf(w, "%s %s\n", name_of_script, scr_name); mc_wlocate(w, 4, 5); mc_wputs(w, question); mc_wredraw(w, 1); while (!done) { mc_wlocate(w, mbslen (question) + 5, 5); n = wxgetch(); if (islower(n)) n = toupper(n); switch (n) { case '\r': case '\n': if (scr_name[0] == '\0') { mc_wbell(); break; } mc_wclose(w, 1); done = 1; break; case 27: /* ESC */ mc_wclose(w, 1); return; case 'A': mc_wlocate(w, mbslen (username) + 1, 1); mc_wclreol(w); scr_user[0] = 0; mc_wgets(w, scr_user, 32, 32); break; case 'B': mc_wlocate(w, mbslen (password) + 1, 2); mc_wclreol(w); scr_passwd[0] = 0; mc_wgets(w, scr_passwd, 32, 32); break; case 'C': mc_wlocate(w, mbslen (name_of_script) + 1, 3); mc_wgets(w, scr_name, 32, 32); break; default: break; } } } else { strncpy(scr_user, l, sizeof(scr_user)); strncpy(scr_name, s, sizeof(scr_name)); strncpy(scr_passwd, p, sizeof(scr_passwd)); } sprintf(scr_lines, "%d", (int) lines); /* jl 13.09.97 */ /* Throw away status line if temporary */ if (tempst) { mc_wclose(st, 1); tempst = 0; st = NULL; } scriptname(scr_name); pipe(pipefd); if (mcd(P_SCRIPTDIR) < 0) return; snprintf(cmdline, sizeof(cmdline), "%s %s %s %s", P_SCRIPTPROG, scr_name, logfname, logfname[0]==0? "": homedir); switch (udpid = fork()) { case -1: werror(_("Out of memory: could not fork()")); close(pipefd[0]); close(pipefd[1]); mcd(""); return; case 0: /* Child */ dup2(portfd, 0); dup2(portfd, 1); dup2(pipefd[1], 2); close(pipefd[0]); close(pipefd[1]); for (n = 1; n < _NSIG; n++) signal(n, SIG_DFL); mc_setenv("LOGIN", scr_user); mc_setenv("PASS", scr_passwd); mc_setenv("TERMLIN", scr_lines); /* jl 13.09.97 */ translated_cmdline = translate(cmdline); if (translated_cmdline != NULL) { fastexec(translated_cmdline); free(translated_cmdline); } exit(1); default: /* Parent */ break; } setcbreak(1); /* Cbreak, no echo */ enab_sig(1, 0); /* But enable SIGINT */ signal(SIGINT, udcatch); close(pipefd[1]); /* pipe output from "runscript" program to terminal emulator */ fds[0].fd = pipefd[0]; /* runscript */ fds[0].events = POLLIN; fds[1].fd = STDIN_FILENO; /* stdin */ fds[1].events = POLLIN; script_running = 1; while (script_running && poll(fds, 2, -1) > 0) for (i = 0; i < 2; i++) { if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) script_running = 0; else if ((fds[i].revents & POLLIN) && (n = read(fds[i].fd, buf, sizeof(buf)-1)) > 0) { ptr = buf; while (n--) if (i) vt_send(*ptr++); else vt_out(*ptr++); timer_update(); mc_wflush(); } } /* Collect status, and clean up. */ m_wait(&status); enab_sig(0, 0); signal(SIGINT, SIG_IGN); setcbreak(2); /* Raw, no echo */ close(pipefd[0]); scriptname(""); mcd(""); }
void updown(int what, int nr) { #ifdef LOG_XFER #warning LOG_XFER defined! FILE *xfl; #endif const char *name[13]; int idx[13]; int r, f, g = 0; char *t = what == 'U' ? _("Upload") : _("Download"); char buf[160]; char buffirst[20]; char xfrstr[160] = ""; char trimbuf[160] = ""; char title[64]; const char *s =""; int pipefd[2]; int n, status; char * cmdline = NULL; char * translated_cmdline = NULL; WIN *win = (WIN *)NULL; if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0) return; /* Automatic? */ if (nr == 0) { for (f = 0; f < 12; f++) { if (P_PNAME(f)[0] && P_PUD(f) == what) { name[g] = P_PNAME(f); idx[g++] = f; } } name[g] = NULL; if (g == 0) return; r = mc_wselect(30, 7, name, NULL, t, stdattr, mfcolor, mbcolor) - 1; if (r < 0) return; g = idx[r]; } else g = nr; buf[0] = 0; /* jseymour file selector with choice of dir on zmodem, etc. download */ #if 1 { int multiple; /* 0:only directory, 1:one file, -1:any number */ size_t cmdline_length; if (P_MUL(g)=='Y') /* need file(s), or just a directory? */ multiple = what == 'U'? -1 : 0; else multiple = 1; /* only one allowed */ if (P_FSELW[0] == 'Y' && (what == 'U' || P_ASKDNDIR[0] == 'Y')) { s = filedir(multiple, what == 'U'? 0 : 1); if (s == NULL) return; } else if (P_PNN(g) == 'Y') { s = input(_("Please enter file names"), buf); if (s == NULL) return; } /* discard directory if "multiple" == 0 */ cmdline_length = strlen(P_PPROG(g)) + strlen((char*) (multiple == 0 ? "" : s)) + 1; /* + 1 for ' ' */ cmdline = malloc(cmdline_length + 1); /* + 1 for NUL */ if (cmdline == NULL) { werror(_("Out of memory: could allocate buffer for command line")); return; } snprintf(cmdline, cmdline_length + 1, "%s %s", P_PPROG(g), multiple == 0 ? "" : s); } #endif if (P_LOGXFER[0] == 'Y') do_log("%s", cmdline); /* jl 22.06.97 */ if (P_PFULL(g) == 'N') { win = mc_wopen(10, 7, 70, 13, BSINGLE, stdattr, mfcolor, mbcolor, 1, 0, 1); snprintf(title, sizeof(title), _("%.30s %s - Press CTRL-C to quit"), P_PNAME(g), what == 'U' ? _("upload") : _("download")); mc_wtitle(win, TMID, title); pipe(pipefd); } else mc_wleave(); m_flush(portfd); switch (udpid = fork()) { case -1: werror(_("Out of memory: could not fork()")); if (win) { close(pipefd[0]); close(pipefd[1]); mc_wclose(win, 1); } else mc_wreturn(); mcd(""); if(cmdline) free(cmdline); return; case 0: /* Child */ if (P_PIORED(g) == 'Y') { dup2(portfd, 0); dup2(portfd, 1); } if (win) { dup2(pipefd[1], 2); close(pipefd[0]); if (pipefd[1] != 2) close(pipefd[1]); } lockfile_remove(); for (n = 1; n < _NSIG; n++) signal(n, SIG_DFL); translated_cmdline = translate(cmdline); if (translated_cmdline != NULL) { fastexec(translated_cmdline); free(translated_cmdline); } if(cmdline) free(cmdline); exit(1); default: /* Parent */ break; } if(cmdline) free(cmdline); if (win) { setcbreak(1); /* Cbreak, no echo. */ enab_sig(1, 0); /* But enable SIGINT */ } signal(SIGINT, udcatch); if (P_PIORED(g) == 'Y') { close(pipefd[1]); #ifdef LOG_XFER xfl=fopen("xfer.log","wb"); #endif while ((n = read(pipefd[0], buf, sizeof(buf))) > 0) { buf[n] = '\0'; mc_wputs(win, buf); timer_update(); /* Log the filenames & sizes jl 14.09.97 */ if (P_LOGXFER[0] == 'Y') { #ifdef LOG_XFER if (xfl) fprintf(xfl,">%s<\n",buf); #endif if (sscanf(buf, "%19s", buffirst)) { /* if / jl 29.09.97 */ if (!strncmp (buffirst, "Receiving", 9) || !strncmp (buffirst, "Sending", 7)) { if (xfrstr[0]) { trim (trimbuf, xfrstr, sizeof(trimbuf)); do_log ("%s", trimbuf); xfrstr[0] = 0; } trim (trimbuf, buf, sizeof(trimbuf)); do_log("%s", trimbuf); } else if (!strncmp (buffirst, "Bytes", 5)) { strncpy (xfrstr, buf, sizeof(xfrstr)); } buffirst[0] = 0; trimbuf[0] = 0; } } } #ifdef LOG_XFER if (xfl) fclose(xfl); #endif } /* Log the last file size jl 14.09.97 */ if (P_LOGXFER[0] == 'Y' && xfrstr[0]) { trim (trimbuf, xfrstr, sizeof(trimbuf)); do_log ("%s", trimbuf); xfrstr[0] = 0; } while (udpid != m_wait(&status)); if (win) { enab_sig(0, 0); signal(SIGINT, SIG_IGN); } if (win == (WIN *)0) mc_wreturn(); lockfile_create(); /* MARK updated 02/17/94 - Flush modem port before displaying READY msg */ /* because a BBS often displays menu text right after a download, and we */ /* don't want the modem buffer to be lost while waiting for key to be hit */ m_flush(portfd); port_init(); setcbreak(2); /* Raw, no echo. */ if (win) close(pipefd[0]); mcd(""); timer_update(); /* If we got interrupted, status != 0 */ if (win && (status & 0xFF00) == 0) { #if VC_MUSIC if (P_SOUND[0] == 'Y') { mc_wprintf(win, _("\n READY: press any key to continue...")); music(); } else sleep(1); #else /* MARK updated 02/17/94 - If there was no VC_MUSIC capability, */ /* then at least make some beeps! */ if (P_SOUND[0] == 'Y') mc_wprintf(win, "\007\007\007"); sleep(1); #endif } if (win) mc_wclose(win, 1); }