#ifndef lint static char rcsid[] = "$Id: main.c,v 4.38 1996/05/29 00:05:15 mikes Exp $"; #endif /* * Program: Main stand-alone Pine Composer routines * * * Michael Seibel * Networks and Distributed Computing * Computing and Communications * University of Washington * Administration Builiding, AG-44 * Seattle, Washington, 98195, USA * Internet: mikes@cac.washington.edu * * Please address all bugs and comments to "pine-bugs@cac.washington.edu" * * * Pine and Pico are registered trademarks of the University of Washington. * No commercial use of these trademarks may be made without prior written * permission of the University of Washington. * * Pine, Pico, and Pilot software and its included text are Copyright * 1989-1996 by the University of Washington. * * The full text of our legal notices is contained in the file called * CPYRIGHT, included with this distribution. * * * WEEMACS/PICO NOTES: * * 08 Jan 92 - removed PINE defines to simplify compiling * * 08 Apr 92 - removed PINE stub calls * */ #include #include #include "osdep.h" /* operating system dependent includes */ #include "pico.h" /* pine composer definitions */ #include "estruct.h" /* global structures and defines */ #include "efunc.h" /* function declarations and sans name table */ #include "edef.h" /* global definitions */ /* * Useful internal prototypes */ #ifdef _WINDOWS int pico_file_drop(int, int, char *); #endif /* * this isn't defined in the library, because it's a pine global * which we use for GetKey's timeout */ int timeoutset = 0; /* * function key mappings */ static int fkm[12][2] = { { F1, (CTRL|'G')}, { F2, (CTRL|'X')}, { F3, (CTRL|'O')}, { F4, (CTRL|'J')}, { F5, (CTRL|'R')}, { F6, (CTRL|'W')}, { F7, (CTRL|'Y')}, { F8, (CTRL|'V')}, { F9, (CTRL|'K')}, { F10, (CTRL|'U')}, { F11, (CTRL|'C')}, #ifdef SPELLER { F12, (CTRL|'T')} #else { F12, (CTRL|'D')} #endif }; void Usage(const char* const prog) { fprintf(stderr, "Usage: %s [-defghjkvVwx?] [-r [col]] [-c[nr][bf] color] " "[-o dir] [file]\n\n", prog); fputs("Pico is a very simple text editor. It is well-suited to basic text " "editing\n tasks (eg it makes a good CVSEDITOR).\n\nOptions " "available:\n", stderr); fputs(" -c: Set a specific screen color (normal/reversed fore/background)" " to `color'.\n `color' can be a color name (uppercase = bright)" " or number (0-15).\n", stderr); fputs(" -e: Toggle availability of filename completion. (Default: On)\n", stderr); fputs(" -f: Toggle showing of function key mnemonics. (Default: Off)\n", stderr); fputs(" -g: Toggle showing of cursor in file browser. (Default: Off)\n", stderr); fputs(" -h, -?: Show this help text and exit.\n", stderr); fputs(" -j: Toggle availability of 'Goto' in file browser. " "(Default: Off)\n", stderr); fputs(" -k: Toggle 'Kill From Dot'. This means that Ctrl-K kills to " "end-of-line\n (like Emacs) instead of killing the entire line." " (Default: Off)\n", stderr); fputs(" -o: Restrict access to files and directories below `dir'.\n", stderr); fputs(" -r: Set fill column to `col'. (Default: 72)\n", stderr); fputs(" -v, -V: Toggle View mode (disables editing). (Default: Off)\n", stderr); fputs(" -w: Toggle word-wrap mode. (Default: On)\n", stderr); fputs(" -x: Toggle availability of keyhelp. (Default: On)\n", stderr); exit(0); } /* * main standalone pico routine */ #ifdef _WINDOWS app_main (argc, argv) #else main(argc, argv) #endif char *argv[]; { register int c; register int f; register int n; register BUFFER *bp; register int carg; /* current arg to scan */ int viewflag = FALSE; /* are we starting in view mode?*/ int starton = 0; /* where's dot to begin with? */ char bname[NBUFN]; /* buffer name of file to read */ char *clerr = NULL; /* garbage on command line */ // Change argv0 clerr = (char*)malloc(NSTRING); _truename(argv[0], clerr); if(!_USE_LFN) strlwr(clerr); free(argv[0]); argv[0] = (char*) malloc(20); fnsplit(clerr, NULL, NULL, argv[0], NULL); free(clerr); clerr = NULL; timeout = 600; Pmaster = NULL; /* turn OFF composer functionality */ km_popped = 0; opertree[0] = '\0'; opertree[NLINE] = '\0'; /* * Read command line flags before initializing, otherwise, we never * know to init for f_keys... */ carg = 1; while(carg < argc){ if(argv[carg][0] == '-'){ switch(argv[carg][1]){ case 'v': /* -v for View File */ case 'V': viewflag = !viewflag; break; case 'e': /* file name completion */ gmode ^= MDCMPLT; break; case 'k': /* kill from dot */ gmode ^= MDDTKILL; break; case 'j': /* allow "Goto" in file browser */ gmode ^= MDGOTO; break; case 'g': /* show-cursor in file browser */ gmode ^= MDSHOCUR; break; case 'm': /* turn on mouse support */ gmode ^= MDMOUSE; break; case 'x': /* suppress keyhelp */ sup_keyhelp = !sup_keyhelp; break; case 'd': /* -d for rebind delete key */ bindtokey(0x7f, forwdel); break; case 'f': /* -f for function key use */ gmode ^= MDFKEY; break; case 'r': /* set fill column */ if(argv[carg][2] != '\0') if((userfillcol = atoi(&argv[carg][2])) < 1) userfillcol = 72; break; case 'n': /* -n for new mail notification */ timeoutset = 1; timeout = 180; if(argv[carg][2] != '\0') if((timeout = atoi(&argv[carg][2])) < 30) timeout = 180; break; case 's' : if(argv[carg+1] && argv[carg+1][0] && argv[carg+1][0] != '-') alt_speller = argv[++carg]; /* BUG: should gripe if test fails */ break; case 't': /* special shutdown mode */ gmode ^= MDTOOL; rebindfunc(wquit, quickexit); break; case 'o' : /* operating tree */ if(argv[carg+1] && argv[carg+1][0] && argv[carg+1][0] != '-'){ strncpy(opertree, argv[++carg], NLINE); gmode ^= MDTREE; } else{ printf("Missing or empty argument to -o flag isn't allowed\n"); exit(1); } break; case 'z': /* -z to suspend */ gmode ^= MDSSPD; break; case 'w': /* -w turn off word wrap */ gmode ^= MDWRAP; break; #if defined(DOS) || defined(OS2) case 'c': /* -c[nr][fb] colors */ if(carg + 1 < argc){ if(argv[carg][2] == 'n'){ if(argv[carg][3] == 'f') pico_nfcolor(argv[++carg]); else if(argv[carg][3] == 'b') pico_nbcolor(argv[++carg]); } else if(argv[carg][2] == 'r'){ if(argv[carg][3] == 'f') pico_rfcolor(argv[++carg]); else if(argv[carg][3] == 'b') pico_rbcolor(argv[++carg]); } } else{ clerr = "insufficient args for \"-c\""; break; } break; #endif case '?': /* -? or -h for usage */ case 'h': Usage(argv[0]); break; default: /* huh? */ clerr = argv[carg]; break; } carg++; } else if(argv[carg][0] == '+'){ /* leading '+' is special */ starton = atoi(&argv[carg][1]); carg++; } else /* pick up file name later... */ break; } if(!vtinit()) /* Displays. */ exit(1); strcpy(bname, "main"); /* default buffer name */ edinit(bname); /* Buffers, windows. */ update(); /* let the user know we are here */ #ifdef _WINDOWS mswin_allowpaste(MSWIN_PASTE_FULL); mswin_setclosetext("Use the ^X command to exit Pico."); mswin_setscrollcallback (pico_scroll_callback); #endif #if defined(TERMCAP) || defined(TERMINFO) || defined(VMS) if(pico_kbesc == NULL){ /* will arrow keys work ? */ (*term.t_putchar)('\007'); emlwrite("Warning: keypad keys may non-functional", NULL); } #endif /* TERMCAP/TERMINFO/VMS */ if(carg < argc){ /* Any file to edit? */ makename(bname, argv[carg]); /* set up a buffer for this file */ bp = curbp; /* read in first file */ strcpy(bp->b_fname, argv[carg]); fixpath(bp->b_fname, NFILEN); makename(bname, bp->b_fname); strcpy(bp->b_bname, bname); if (readin(bp->b_fname, (viewflag==FALSE)) == ABORT) { strcpy(bp->b_bname, "main"); strcpy(bp->b_fname, ""); } bp->b_dotp = bp->b_linep; bp->b_doto = 0; if (viewflag) /* set the view mode */ bp->b_mode |= MDVIEW; } /* setup to process commands */ lastflag = 0; /* Fake last flags. */ curbp->b_mode |= gmode; /* and set default modes*/ curwp->w_flag |= WFMODE; /* and force an update */ if(timeoutset) emlwrite("Checking for new mail every %D seconds", (void *)timeout); if(clerr){ /* post any errors on command line */ if(mpresf) /* show earlier message though! */ sleep(2); emlwrite("\007Unknown option: %s", clerr); } forwline(0, starton - 1); /* move dot to specified line */ while(1){ if(km_popped){ km_popped--; if(km_popped == 0) /* cause bottom three lines to be repainted */ curwp->w_flag |= WFHARD; } if(km_popped){ /* temporarily change to cause menu to be painted */ term.t_mrow = 2; curwp->w_ntrows -= 2; curwp->w_flag |= WFMODE; movecursor(term.t_nrow-2, 0); /* clear status line, too */ peeol(); } update(); /* Fix up the screen */ if(km_popped){ term.t_mrow = 0; curwp->w_ntrows += 2; } #ifdef MOUSE #ifdef EX_MOUSE /* New mouse function for real mouse text seletion. */ register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow + 1), term.t_ncol); #else mouse_in_content(K_MOUSE, -1, -1, 0, 0); register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1), term.t_ncol); #endif #endif #ifdef _WINDOWS mswin_setdndcallback (pico_file_drop); #endif c = GetKey(); #ifdef MOUSE #ifdef EX_MOUSE clear_mfunc(mouse_in_pico); #else clear_mfunc(mouse_in_content); #endif #endif #ifdef _WINDOWS mswin_cleardndcallback (); #endif if(timeoutset && (c == NODATA || time_to_check())){ if(pico_new_mail()) emlwrite("You may possibly have new mail.", NULL); } if(km_popped) switch(c){ case NODATA: case (CTRL|'L'): km_popped++; break; default: /* clear bottom three lines */ mlerase(); break; } if(c == NODATA) continue; if(mpresf){ /* erase message line? */ if(mpresf++ > MESSDELAY) mlerase(); } f = FALSE; n = 1; #ifdef MOUSE clear_mfunc(mouse_in_content); #endif /* Do it. */ execute(normalize_cmd(c, fkm, 1), f, n); } return 0; } #ifdef _WINDOWS /* * */ int pico_file_drop(x, y, filename) int x, y; char *filename; { /* * if current buffer is unchanged * *or* "new buffer" and no current text */ if(((curwp->w_bufp->b_flag & BFCHG) == 0) || (curwp->w_bufp->b_fname[0] == '\0' && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep) && curwp->w_doto == 0)){ register BUFFER *bp = curwp->w_bufp; char bname[NBUFN]; strcpy(bp->b_fname, filename); fixpath(bp->b_fname, NFILEN); makename(bname, bp->b_fname); strcpy(bp->b_bname, bname); bp->b_flag &= ~BFCHG; /* turn off change bit */ if (readin(filename, 1) == ABORT) { strcpy(bp->b_bname, ""); strcpy(bp->b_fname, ""); } bp->b_dotp = bp->b_linep; bp->b_doto = 0; } else{ ifile(filename); curwp->w_flag |= WFHARD; update(); emlwrite("Inserted dropped file \"%s\"", filename); } curwp->w_flag |= WFHARD; update(); /* restore cursor */ return(1); } #endif