* Color support for the default composer and Pico. If users have
[alpine.git] / pico / main.c
blob1123b467daeebf4bcf8be1f62b751e9e4af260e1
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: main.c 1184 2008-12-16 23:52:15Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2008 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
20 * Program: Main stand-alone Pine Composer routines
23 * WEEMACS/PICO NOTES:
25 * 08 Jan 92 - removed PINE defines to simplify compiling
27 * 08 Apr 92 - removed PINE stub calls
31 #include "headers.h"
32 #include "../c-client/mail.h"
33 #include "../c-client/rfc822.h"
34 #include "../c-client/utf8.h"
35 #include "../pith/osdep/collate.h"
36 #include "../pith/charconv/filesys.h"
37 #include "../pith/charconv/utf8.h"
38 #include "../pith/conf.h"
41 * Useful internal prototypes
43 #ifdef _WINDOWS
44 int pico_file_drop(int, int, char *);
45 #endif
48 * this isn't defined in the library, because it's a pine global
49 * which we use for GetKey's timeout
51 int timeoutset = 0;
54 int my_timer_period = (300 * 1000);
57 * function key mappings
59 static UCS fkm[12][2] = {
60 { F1, (CTRL|'G')},
61 { F2, (CTRL|'X')},
62 { F3, (CTRL|'O')},
63 { F4, (CTRL|'J')},
64 { F5, (CTRL|'R')},
65 { F6, (CTRL|'W')},
66 { F7, (CTRL|'Y')},
67 { F8, (CTRL|'V')},
68 { F9, (CTRL|'K')},
69 { F10, (CTRL|'U')},
70 { F11, (CTRL|'C')},
71 #ifdef SPELLER
72 { F12, (CTRL|'T')}
73 #else
74 { F12, (CTRL|'D')}
75 #endif
78 char *pico_args(int, char **, int *, int *, int *);
79 void pico_args_help(void);
80 void pico_vers_help(void);
81 void pico_display_args_err(char *, char **, int);
82 PCOLORS *pico_set_global_colors(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
83 void display_color_codes(void);
86 /* TRANSLATORS: An error message about an unknown flag (option)
87 on the command line */
88 char args_pico_missing_flag[] = N_("unknown flag \"%c\"");
89 /* TRANSLATORS: error message about command line */
90 char args_pico_missing_arg[] = N_("missing or empty argument to \"%c\" flag");
91 char args_pico_missing_num[] = N_("non numeric argument for \"%c\" flag");
92 char args_pico_missing_color[] = N_("missing color for \"%s\" flag");
93 char args_pico_missing_charset[] = N_("missing character set for \"%s\" flag");
94 char args_pico_input_charset[] = N_("input character set \"%s\" is unsupported");
95 char args_pico_output_charset[] = N_("output character set \"%s\" is unsupported");
97 char *args_pico_args[] = {
98 /* TRANSLATORS: little help printed out when incorrect arguments
99 are given to pico program. */
100 N_("Possible Starting Arguments for Pico editor:"),
102 N_("\tArgument\t\tMeaning"),
103 N_("\t -e \t\tComplete - allow file name completion"),
104 N_("\t -k \t\tCut - let ^K cut from cursor position to end of line"),
105 N_("\t -a \t\tShowDot - show dot files in file browser"),
106 N_("\t -j \t\tGoto - allow 'Goto' command in file browser"),
107 N_("\t -g \t\tShow - show cursor in file browser"),
108 N_("\t -m \t\tMouse - turn on mouse support"),
109 N_("\t -x \t\tNoKeyhelp - suppress keyhelp"),
110 N_("\t -p \t\tPreserveStartStop - preserve \"start\"(^Q) and \"stop\"(^S) characters"),
111 N_("\t -q \t\tTermdefWins - termcap or terminfo takes precedence over defaults"),
112 N_("\t -Q <quotestr> \tSet quote string (eg. \"> \") esp. for composing email"),
113 N_("\t -d \t\tRebind - let delete key delete current character"),
114 N_("\t -f \t\tKeys - force use of function keys"),
115 N_("\t -b \t\tReplace - allow search and replace"),
116 N_("\t -h \t\tHelp - give this list of options"),
117 N_("\t -r[#cols] \tFill - set fill column to #cols columns, default=72"),
118 N_("\t -n[#s] \tMail - notify about new mail every #s seconds, default=180"),
119 N_("\t -s <speller> \tSpeller - specify alternative speller"),
120 N_("\t -t \t\tShutdown - enable special shutdown mode"),
121 N_("\t -o <dir>\tOperation - specify the operating directory"),
122 N_("\t -z \t\tSuspend - allow use of ^Z suspension"),
123 N_("\t -w \t\tNoWrap - turn off word wrap"),
124 N_("\t -W <wordseps> \tSet word separators other than whitespace"),
125 #ifndef _WINDOWS
126 N_("\t -dcs <display_character_set> \tdefault uses LANG or LC_CTYPE from environment"),
127 N_("\t -kcs <keyboard_character_set> \tdefaults to display_character_set"),
128 N_("\t -syscs\t\tuse system-supplied translation routines"),
129 #endif /* ! _WINDOWS */
130 #ifdef _WINDOWS
131 N_("\t -cnf color \tforeground color"),
132 N_("\t -cnb color \tbackground color"),
133 N_("\t -crf color \treverse foreground color"),
134 N_("\t -crb color \treverse background color"),
135 #endif /* _WINDOWS */
136 N_("\t -color_code \tdisplay number codes for different colors"),
137 N_("\t -ncolors number \tnumber of colors for screen (8, 16, or 256)"),
138 N_("\t -ntfc number \tnumber of color of foreground text"),
139 N_("\t -ntbc number \tnumber of color of the background"),
140 N_("\t -rtfc number \tnumber of color of reverse text"),
141 N_("\t -rtbc number \tnumber of color of reverse background"),
142 N_("\t -tbfc number \tnumber of color of foreground (text) of the title bar"),
143 N_("\t -tbbc number \tnumber of color of background of the title bar"),
144 N_("\t -klfc number \tnumber of color of foreground (text) of the key label"),
145 N_("\t -klbc number \tnumber of color of background of the key label"),
146 N_("\t -knfc number \tnumber of color of foreground (text) of the key name"),
147 N_("\t -knbc number \tnumber of color of background of the key name"),
148 N_("\t -stfc number \tnumber of color of foreground (text) of the status line"),
149 N_("\t -stbc number \tnumber of color of background of the status line"),
150 N_("\t -prfc number \tnumber of color of foreground (text) of a prompt"),
151 N_("\t -prbc number \tnumber of color of background of a prompt"),
152 N_("\t -q1fc number \tnumber of color of foreground (text) of level one of quoted text"),
153 N_("\t -q1bc number \tnumber of color of background of level one of quoted text"),
154 N_("\t -q2fc number \tnumber of color of foreground (text) of level two of quoted text"),
155 N_("\t -q2bc number \tnumber of color of background of level two of quoted text"),
156 N_("\t -q3fc number \tnumber of color of foreground (text) of level three of quoted text"),
157 N_("\t -q3bc number \tnumber of color of background of level three of quoted text"),
158 N_("\t -sbfc number \tnumber of color of foreground of signature block text"),
159 N_("\t -sbbc number \tnumber of color of background of signature block text"),
160 N_("\t +[line#] \tLine - start on line# line, default=1"),
161 N_("\t -v \t\tView - view file"),
162 N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"),
163 N_("\t -version\tPico version number"),
164 "",
165 N_("\t All arguments may be followed by a file name to display."),
167 NULL
172 * main standalone pico routine
174 #ifdef _WINDOWS
176 app_main (int argc, char *argv[])
177 #else
179 main(int argc, char *argv[])
180 #endif
182 UCS c;
183 register int f;
184 register int n;
185 register BUFFER *bp;
186 int viewflag = FALSE; /* are we starting in view mode?*/
187 int starton = 0; /* where's dot to begin with? */
188 int setlocale_collate = 1;
189 char bname[NBUFN]; /* buffer name of file to read */
190 char *file_to_edit = NULL;
191 char *display_charmap = NULL, *dc;
192 char *keyboard_charmap = NULL;
193 int use_system = 0;
194 char *err = NULL;
196 #ifndef _WINDOWS
197 utf8_parameters(SET_UCS4WIDTH, (void *) pith_ucs4width);
198 #endif /* _WINDOWS */
200 set_input_timeout(600);
201 Pmaster = NULL; /* turn OFF composer functionality */
202 km_popped = 0;
205 * Read command line flags before initializing, otherwise, we never
206 * know to init for f_keys...
208 file_to_edit = pico_args(argc, argv, &starton, &viewflag, &setlocale_collate);
210 set_collation(setlocale_collate, 1);
212 #define cpstr(s) strcpy((char *)fs_get(1+strlen(s)), s)
214 #ifdef _WINDOWS
215 init_utf8_display(1, NULL);
216 #else /* UNIX */
219 if(display_character_set)
220 display_charmap = cpstr(display_character_set);
221 #if HAVE_LANGINFO_H && defined(CODESET)
222 else if((dc = nl_langinfo_codeset_wrapper()) != NULL)
223 display_charmap = cpstr(dc);
224 #endif
226 if(!display_charmap)
227 display_charmap = cpstr("US-ASCII");
229 if(keyboard_character_set)
230 keyboard_charmap = cpstr(keyboard_character_set);
231 else
232 keyboard_charmap = cpstr(display_charmap);
235 if(use_system_translation){
236 #if PREREQ_FOR_SYS_TRANSLATION
237 use_system++;
238 /* This modifies its arguments */
239 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
240 &input_cs, &err) == -1){
241 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
242 exit(1);
244 else if(err){
245 fprintf(stderr, "%s\n", err);
246 fs_give((void **) &err);
248 #endif
251 if(!use_system){
252 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
253 &input_cs, &err) == -1){
254 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
255 exit(1);
257 else if(err){
258 fprintf(stderr, "%s\n", err);
259 fs_give((void **) &err);
263 if(keyboard_charmap){
264 set_locale_charmap(keyboard_charmap);
265 free((void *) keyboard_charmap);
268 if(display_charmap)
269 free((void *) display_charmap);
271 #endif /* UNIX */
274 * There are a couple arguments that we need to be sure
275 * are converted for internal use.
277 if(alt_speller)
278 alt_speller = cpstr(fname_to_utf8(alt_speller));
280 if(opertree && opertree[0]){
281 strncpy(opertree, fname_to_utf8(opertree), sizeof(opertree));
282 opertree[sizeof(opertree)-1] = '\0';
285 if(glo_quote_str_orig)
286 glo_quote_str = utf8_to_ucs4_cpystr(fname_to_utf8(glo_quote_str_orig));
288 if(glo_wordseps_orig)
289 glo_wordseps = utf8_to_ucs4_cpystr(fname_to_utf8(glo_wordseps_orig));
291 if(file_to_edit)
292 file_to_edit = cpstr(fname_to_utf8(file_to_edit));
294 #undef cpstr
296 #if defined(DOS) || defined(OS2)
297 if(file_to_edit){ /* strip quotes? */
298 int l;
300 if(strchr("'\"", file_to_edit[0])
301 && (l = strlen(file_to_edit)) > 1
302 && file_to_edit[l-1] == file_to_edit[0]){
303 file_to_edit[l-1] = '\0'; /* blat trailing quote */
304 file_to_edit++; /* advance past leading quote */
307 #endif
309 if(!vtinit()) /* Displays. */
310 exit(1);
312 strncpy(bname, "main", sizeof(bname)); /* default buffer name */
313 bname[sizeof(bname)-1] = '\0';
314 edinit(bname); /* Buffers, windows. */
316 update(); /* let the user know we are here */
317 sgarbf = TRUE; /* next update, repaint all */
319 #ifdef _WINDOWS
320 mswin_setwindow(NULL, NULL, NULL, NULL, NULL, NULL);
321 mswin_showwindow();
322 mswin_showcaret(1); /* turn on for main window */
323 mswin_allowpaste(MSWIN_PASTE_FULL);
324 mswin_setclosetext("Use the ^X command to exit Pico.");
325 mswin_setscrollcallback (pico_scroll_callback);
326 #endif
328 #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
329 if(kbesc == NULL){ /* will arrow keys work ? */
330 (*term.t_putchar)('\007');
331 emlwrite("Warning: keypad keys may be non-functional", NULL);
333 #endif /* USE_TERMCAP/USE_TERMINFO/VMS */
335 if(file_to_edit){ /* Any file to edit? */
337 makename(bname, file_to_edit); /* set up a buffer for this file */
339 bp = curbp; /* read in first file */
340 makename(bname, file_to_edit);
341 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
342 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
344 if(strlen(file_to_edit) >= NFILEN){
345 char buf[128];
347 snprintf(buf, sizeof(buf), "Filename \"%.10s...\" too long", file_to_edit);
348 emlwrite(buf, NULL);
349 file_to_edit = NULL;
351 else{
352 strncpy(bp->b_fname, file_to_edit, sizeof(bp->b_fname));
353 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
354 if (((gmode&MDTREE) && !in_oper_tree(file_to_edit)) ||
355 readin(file_to_edit, (viewflag==FALSE), TRUE) == ABORT) {
356 if ((gmode&MDTREE) && !in_oper_tree(file_to_edit)){
357 EML eml;
358 eml.s = opertree;
359 emlwrite(_("Can't read file from outside of %s"), &eml);
362 file_to_edit = NULL;
366 if(!file_to_edit){
367 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
368 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
369 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
370 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
373 bp->b_dotp = bp->b_linep;
374 bp->b_doto = 0;
376 if (viewflag) /* set the view mode */
377 bp->b_mode |= MDVIEW;
380 /* setup to process commands */
381 lastflag = 0; /* Fake last flags. */
382 curbp->b_mode |= gmode; /* and set default modes*/
384 curwp->w_flag |= WFMODE; /* and force an update */
386 if(timeoutset){
387 EML eml;
389 eml.s = comatose(get_input_timeout());
390 emlwrite(_("Checking for new mail every %s seconds"), &eml);
394 forwline(0, starton - 1); /* move dot to specified line */
396 while(1){
398 if(km_popped){
399 km_popped--;
400 if(km_popped == 0) /* cause bottom three lines to be repainted */
401 curwp->w_flag |= WFHARD;
404 if(km_popped){ /* temporarily change to cause menu to be painted */
405 term.t_mrow = 2;
406 curwp->w_ntrows -= 2;
407 curwp->w_flag |= WFMODE;
408 movecursor(term.t_nrow-2, 0); /* clear status line, too */
409 peeol();
412 if(km_popped){
413 term.t_mrow = 0;
414 curwp->w_ntrows += 2;
417 update(); /* Fix up the screen */
419 #ifdef MOUSE
420 #ifdef EX_MOUSE
421 /* New mouse function for real mouse text seletion. */
422 register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow + 1),
423 term.t_ncol);
424 #else
425 mouse_in_content(KEY_MOUSE, -1, -1, 0, 0);
426 register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1),
427 term.t_ncol);
428 #endif
429 #endif
430 #ifdef _WINDOWS
431 mswin_setdndcallback (pico_file_drop);
432 mswin_mousetrackcallback(pico_cursor);
433 #endif
434 c = GetKey();
435 #ifdef MOUSE
436 #ifdef EX_MOUSE
437 clear_mfunc(mouse_in_pico);
438 #else
439 clear_mfunc(mouse_in_content);
440 #endif
441 #endif
442 #ifdef _WINDOWS
443 mswin_cleardndcallback ();
444 mswin_mousetrackcallback(NULL);
445 #endif
447 if(timeoutset && (c == NODATA || time_to_check())){
448 if(pico_new_mail())
449 emlwrite(_("You may possibly have new mail."), NULL);
452 if(km_popped)
453 switch(c){
454 case NODATA:
455 case (CTRL|'L'):
456 km_popped++;
457 break;
459 default:
460 /* clear bottom three lines */
461 mlerase();
462 break;
465 if(c == NODATA)
466 continue;
468 if(mpresf){ /* erase message line? */
469 if(mpresf++ > MESSDELAY)
470 mlerase();
473 f = FALSE;
474 n = 1;
476 #ifdef MOUSE
477 clear_mfunc(mouse_in_content);
478 #endif
479 /* Do it. */
480 execute(normalize_cmd(c, fkm, 1), f, n);
484 void
485 display_color_codes(void)
487 #define SPACES " "
488 int i, j, k, l, a, len, len_entry, row;
489 int ncolors;
490 COLOR_PAIR *lastc = NULL, *newcp;
491 char *fg;
493 /* this is the format "SPACE COLORED_SPACES = CODE SPACE" */
494 vtterminalinfo(gmode & MDTCAPWINS);
495 (*term.t_open)();
496 (*term.t_rev)(FALSE);
498 pico_toggle_color(1);
499 if((ncolors = pico_count_in_color_table()) <= 0){
500 fprintf(stderr, "%s", "Your screen does not support colors\r\n");
501 exit(1);
505 if(term.t_ncol < 62 || term.t_nrow < 23){
506 fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n");
507 exit(1);
511 fprintf(stdout, "%s", "The code of a color is the number in the same row plus\r\n");
512 fprintf(stdout, "%s", "the number in the same column as that color.\r\n\r\n");
514 lastc = pico_get_cur_color();
515 switch(ncolors){
516 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
517 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
518 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
519 default : fprintf(stderr, "Unknown number of colors %d\n", ncolors);
520 exit(1);
521 break;
524 if(ncolors != 256){
525 for(k = -1; 16*k < ncolors; k++){
526 for(l = -1; l < ncolors; l++){
527 if(k == -1){
528 if(ncolors == 8){
529 if(l == -1)
530 fprintf(stdout, "%s", " ");
531 else
532 fprintf(stdout, "%3d", l);
535 else{
536 if(l == -1){
537 pico_toggle_color(1);
538 fprintf(stdout, "%3d ", k);
540 else{
541 if(ncolors || l < 8){
542 i = 16*k + l;
543 newcp = new_color_pair(colorx(0), colorx(i));
544 pico_set_colorp(newcp, PSC_NONE);
545 fprintf(stdout, "%s", SPACES);
546 pico_set_colorp(lastc, PSC_NONE);
551 pico_toggle_color(0);
552 if(k == 0)
553 fprintf(stdout, " (%d colors)", ncolors);
554 if(k != -1 || ncolors == 8)
555 fprintf(stdout, "%s", "\r\n");
557 } else {
558 fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n");
559 a = 16;
560 for(k = -1; 36*k < ncolors; k++){
561 for(l = -1; l < ncolors && l < 16; l++){
562 if(k == -1){
563 if(l == -1)
564 fprintf(stdout, "%s", " ");
565 else
566 fprintf(stdout, "%3d", l);
568 else{
569 if(l == -1){
570 pico_toggle_color(1);
571 fprintf(stdout, "%3d ", 36*k);
573 else{
574 i = 36*k + l;
575 newcp = new_color_pair(colorx(0), colorx(i));
576 pico_set_colorp(newcp, PSC_NONE);
577 fprintf(stdout, "%s", SPACES);
578 pico_set_colorp(lastc, PSC_NONE);
582 pico_toggle_color(0);
583 fprintf(stdout, "%s", "\r\n");
585 a = 20;
586 for(k = -1; 16 + 36*k < ncolors; k++){
587 for(l = -1; l < ncolors && l < a; l++){
588 if(k == -1){
589 if(l == -1)
590 fprintf(stdout, "%s", " ");
591 else
592 fprintf(stdout, "%3d", l);
594 else{
595 if(l == -1){
596 pico_toggle_color(1);
597 fprintf(stdout, "%3d ", 16 + 36*k);
599 else{
600 i = 16 + 36*k + l;
601 newcp = new_color_pair(colorx(0), colorx(i));
602 pico_set_colorp(newcp, PSC_NONE);
603 fprintf(stdout, "%s", SPACES);
604 pico_set_colorp(lastc, PSC_NONE);
608 pico_toggle_color(0);
609 fprintf(stdout, "%s", "\r\n");
612 pico_set_colorp(lastc, PSC_NONE);
617 * Parse the command line args.
619 * Args ac
620 * av
621 * starton -- place to return starton value
622 * viewflag -- place to return viewflag value
624 * Result: command arguments parsed
625 * possible printing of help for command line
626 * various global flags set
627 * returns the name of any file to open, else NULL
629 char *
630 pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate)
632 int c, usage = 0;
633 char *str;
634 char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */
635 int ncolors, ntfc, ntbc, rtfc, rtbc;
636 int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc;
637 int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc;
639 ncolors = 0;
640 ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc =
641 knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc =
642 q3fc = q3bc = sbfc = sbbc = -1;
643 Loop:
644 /* while more arguments with leading - or + */
645 while(--ac > 0 && (**++av == '-' || **av == '+')){
646 if(**av == '+'){
647 if(*++*av)
648 str = *av;
649 else if(--ac)
650 str = *++av;
651 else{
652 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '+');
653 pico_display_args_err(tmp_1k_buf, NULL, 1);
654 usage++;
655 goto Loop;
658 if(!isdigit((unsigned char)str[0])){
659 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '+');
660 pico_display_args_err(tmp_1k_buf, NULL, 1);
661 usage++;
664 if(starton)
665 *starton = atoi(str);
667 goto Loop;
670 /* while more chars in this argument */
671 else while(*++*av){
673 if(strcmp(*av, "version") == 0){
674 pico_vers_help();
676 else if(strcmp(*av, "ntfc") == 0
677 || strcmp(*av, "ntbc") == 0
678 || strcmp(*av, "rtfc") == 0
679 || strcmp(*av, "rtbc") == 0
680 || strcmp(*av, "tbfc") == 0
681 || strcmp(*av, "tbbc") == 0
682 || strcmp(*av, "klfc") == 0
683 || strcmp(*av, "klbc") == 0
684 || strcmp(*av, "knfc") == 0
685 || strcmp(*av, "knbc") == 0
686 || strcmp(*av, "stfc") == 0
687 || strcmp(*av, "stbc") == 0
688 || strcmp(*av, "prfc") == 0
689 || strcmp(*av, "prbc") == 0
690 || strcmp(*av, "q1fc") == 0
691 || strcmp(*av, "q1bc") == 0
692 || strcmp(*av, "q2fc") == 0
693 || strcmp(*av, "q2bc") == 0
694 || strcmp(*av, "q3fc") == 0
695 || strcmp(*av, "q3bc") == 0
696 || strcmp(*av, "sbfc") == 0
697 || strcmp(*av, "sbbc") == 0
698 || strcmp(*av, "ncolors") == 0){
699 str = *av;
700 if(--ac)
701 ++av;
702 else{
703 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-');
704 pico_display_args_err(tmp_1k_buf, NULL, 1);
705 usage++;
706 goto Loop;
709 if(!isdigit((unsigned char)**av)){
710 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-');
711 pico_display_args_err(tmp_1k_buf, NULL, 1);
712 usage++;
714 if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av);
715 else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av);
716 else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av);
717 else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av);
718 else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av);
719 else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av);
720 else if (strcmp(str, "klfc") == 0) klfc = atoi(*av);
721 else if (strcmp(str, "klbc") == 0) klbc = atoi(*av);
722 else if (strcmp(str, "knfc") == 0) knfc = atoi(*av);
723 else if (strcmp(str, "knbc") == 0) knbc = atoi(*av);
724 else if (strcmp(str, "stfc") == 0) stfc = atoi(*av);
725 else if (strcmp(str, "stbc") == 0) stbc = atoi(*av);
726 else if (strcmp(str, "prfc") == 0) prfc = atoi(*av);
727 else if (strcmp(str, "prbc") == 0) prbc = atoi(*av);
728 else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av);
729 else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av);
730 else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av);
731 else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av);
732 else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av);
733 else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av);
734 else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av);
735 else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av);
736 else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av);
737 if(!strcmp(str, "ncolors")){
738 switch(ncolors){
739 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
740 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
741 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
742 default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors);
743 pico_display_args_err(tmp_1k_buf, NULL, 1);
744 exit(1);
745 break;
748 goto Loop;
750 else if(strcmp(*av, "color_codes") == 0){
751 display_color_codes();
752 exit(0);
754 else if(strcmp(*av, "no_setlocale_collate") == 0){
755 *setlocale_collate = 0;
756 goto Loop;
758 #ifndef _WINDOWS
759 else if(strcmp(*av, "syscs") == 0){
760 use_system_translation = !use_system_translation;
761 goto Loop;
763 #endif /* ! _WINDOWS */
764 #ifdef _WINDOWS
765 else if(strcmp(*av, "cnf") == 0
766 || strcmp(*av, "cnb") == 0
767 || strcmp(*av, "crf") == 0
768 || strcmp(*av, "crb") == 0){
770 char *cmd = *av; /* save it to use below */
772 if(--ac){
773 str = *++av;
774 if(cmd[1] == 'n'){
775 if(cmd[2] == 'f')
776 pico_nfcolor(str);
777 else if(cmd[2] == 'b')
778 pico_nbcolor(str);
780 else if(cmd[1] == 'r'){
781 if(cmd[2] == 'f')
782 pico_rfcolor(str);
783 else if(cmd[2] == 'b')
784 pico_rbcolor(str);
787 else{
788 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_color), cmd);
789 pico_display_args_err(tmp_1k_buf, NULL, 1);
790 usage++;
793 goto Loop;
795 #endif /* _WINDOWS */
796 #ifndef _WINDOWS
797 else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
798 char *cmd = *av;
800 if(--ac){
801 if(strcmp(*av, "dcs") == 0){
802 display_character_set = *++av;
803 if(!output_charset_is_supported(display_character_set)){
804 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_output_charset), display_character_set);
805 pico_display_args_err(tmp_1k_buf, NULL, 1);
806 usage++;
809 else{
810 keyboard_character_set = *++av;
811 if(!input_charset_is_supported(keyboard_character_set)){
812 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_input_charset), keyboard_character_set);
813 pico_display_args_err(tmp_1k_buf, NULL, 1);
814 usage++;
818 else{
819 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_charset), cmd);
820 pico_display_args_err(tmp_1k_buf, NULL, 1);
821 usage++;
824 goto Loop;
826 #endif /* ! _WINDOWS */
829 * Single char options.
831 switch(c = **av){
833 * These don't take arguments.
835 case 'a':
836 gmode ^= MDDOTSOK; /* show dot files */
837 break;
838 case 'b':
839 #ifdef notdef
841 * Make MDREPLACE always on instead
842 * Don't leave this to allow turning off of MDREPLACE because the
843 * polarity of -b will have changed. Don't think anybody wants to
844 * turn it off.
846 gmode ^= MDREPLACE; /* -b for replace string in where is command */
847 #endif
848 break;
849 case 'd': /* -d for rebind delete key */
850 bindtokey(0x7f, forwdel);
851 break;
852 case 'e': /* file name completion */
853 gmode ^= MDCMPLT;
854 break;
855 case 'f': /* -f for function key use */
856 gmode ^= MDFKEY;
857 break;
858 case 'g': /* show-cursor in file browser */
859 gmode ^= MDSHOCUR;
860 break;
861 case 'h':
862 usage++;
863 break;
864 case 'j': /* allow "Goto" in file browser */
865 gmode ^= MDGOTO;
866 break;
867 case 'k': /* kill from dot */
868 gmode ^= MDDTKILL;
869 break;
870 case 'm': /* turn on mouse support */
871 gmode ^= MDMOUSE;
872 break;
873 case 'p':
874 preserve_start_stop = 1;
875 break;
876 case 'q': /* -q for termcap takes precedence */
877 gmode ^= MDTCAPWINS;
878 break;
879 case 't': /* special shutdown mode */
880 gmode ^= MDTOOL;
881 rebindfunc(wquit, quickexit);
882 break;
883 case 'v': /* -v for View File */
884 case 'V':
885 *viewflag = !*viewflag;
886 break; /* break back to inner-while */
887 case 'w': /* -w turn off word wrap */
888 gmode ^= MDWRAP;
889 break;
890 case 'x': /* suppress keyhelp */
891 sup_keyhelp = !sup_keyhelp;
892 break;
893 case 'z': /* -z to suspend */
894 gmode ^= MDSSPD;
895 break;
898 * These do take arguments.
900 case 'r': /* set fill column */
901 case 'n': /* -n for new mail notification */
902 case 's' : /* speller */
903 case 'o' : /* operating tree */
904 case 'Q' : /* Quote string */
905 case 'W' : /* Word separators */
906 if(*++*av)
907 str = *av;
908 else if(--ac)
909 str = *++av;
910 else{
911 if(c == 'r')
912 str= "72";
913 else if(c == 'n')
914 str = "180";
915 else{
916 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), c);
917 pico_display_args_err(tmp_1k_buf, NULL, 1);
918 usage++;
919 goto Loop;
923 switch(c){
924 case 's':
925 alt_speller = str;
926 break;
927 case 'o':
928 strncpy(opertree, str, NLINE);
929 gmode ^= MDTREE;
930 break;
931 case 'Q':
932 glo_quote_str_orig = str;
933 break;
934 case 'W':
935 glo_wordseps_orig = str;
936 break;
938 /* numeric args */
939 case 'r':
940 case 'n':
941 if(!isdigit((unsigned char)str[0])){
942 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), c);
943 pico_display_args_err(tmp_1k_buf, NULL, 1);
944 usage++;
947 if(c == 'r'){
948 if((userfillcol = atoi(str)) < 1)
949 userfillcol = 72;
951 else{
952 timeoutset = 1;
953 set_input_timeout(180);
954 if(set_input_timeout(atoi(str)) < 30)
955 set_input_timeout(180);
958 break;
961 goto Loop;
963 default: /* huh? */
964 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_flag), c);
965 pico_display_args_err(tmp_1k_buf, NULL, 1);
966 usage++;
967 break;
972 if(usage)
973 pico_args_help();
975 Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc,
976 tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc,
977 q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc);
979 /* return the first filename for editing */
980 if(ac > 0)
981 return(*av);
982 else
983 return(NULL);
987 PCOLORS *
988 pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg,
989 int tbfg, int tbbg, int klfg, int klbg,
990 int knfg, int knbg, int stfg, int stbg, int prfg, int prbg,
991 int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg,
992 int sbfg, int sbbg)
994 PCOLORS *pcolors = NULL;
995 char *fg, *bg;
997 if(nc != 0 && nc != 8 && nc != 16 && nc != 256){
998 fprintf(stderr, "number of colors must be either 8, 16 or 256\n");
999 exit(1);
1002 if(nc == 0){
1003 if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 ||
1004 klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 ||
1005 stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 ||
1006 q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 ||
1007 q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 ||
1008 rtfg != -1 || rtbg != -1){
1009 fprintf(stderr, "can not specify color numbers without specifying number of colors\n");
1010 exit(1);
1012 else
1013 return pcolors; /* no colors used */
1016 if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc
1017 || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc
1018 || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc
1019 || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc
1020 || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc
1021 || rtfg >= nc || rtbg >= nc){
1022 fprintf(stderr, "Error: specified a color bigger than number of colors\n");
1023 exit(1);
1026 /* Finally, we set up colors */
1027 pico_toggle_color(0);
1028 switch(nc){
1029 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
1030 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
1031 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
1032 default : break; /* impossible case */
1034 pico_toggle_color(1);
1036 pcolors = (PCOLORS *) malloc(sizeof(PCOLORS));
1037 memset((void *)pcolors, 0, sizeof(PCOLORS));
1038 /* ignore bad pair settings, also we set tbcp backwards because it will
1039 * be reversed later in the modeline function, so tbcp->fg is actually
1040 * tbcp->bg and viceversa.
1042 if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */
1043 fg = colorx(ntfg); bg = colorx(ntbg);
1044 pcolors->ntcp = new_color_pair(fg, bg);
1045 pico_nfcolor(fg);
1046 pico_nbcolor(bg);
1048 /* reverse means reverse of normal text */
1049 if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){
1050 rtfg = ntbg;
1051 rtbg = ntfg;
1053 if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */
1054 fg = colorx(rtfg); bg = colorx(rtbg);
1055 pcolors->rtcp = new_color_pair(fg, bg);
1056 pico_rfcolor(fg);
1057 pico_rbcolor(bg);
1059 /* If the user does not specify this, we will set up all
1060 * backgrounds for text to the normal text background
1062 if(ntbg >= 0){
1063 if(knbg < 0) knbg = ntbg;
1064 if(q1bg < 0) q1bg = ntbg;
1065 if(q2bg < 0) q2bg = ntbg;
1066 if(q3bg < 0) q3bg = ntbg;
1067 if(sbbg < 0) sbbg = ntbg;
1069 if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */
1070 if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/
1071 tbfg = rtfg; tbbg = rtbg;
1073 if(klfg < 0 || klbg < 0){ /* set key label colors */
1074 klfg = rtfg; klbg = rtbg;
1076 if(stfg < 0 || stbg < 0){ /* set status colors */
1077 stfg = rtfg; stbg = rtbg;
1079 if(prfg >= 0 && prbg >= 0){ /* set prompt colors */
1080 prfg = rtfg; prbg = rtbg;
1083 if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */
1084 pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg));
1085 if(klfg >= 0 && klbg >= 0) /* set key label colors */
1086 pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg));
1087 if(knfg >= 0 && knbg >= 0) /* set key name colors */
1088 pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg));
1089 if(stfg >= 0 && stbg >= 0) /* set status colors */
1090 pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg));
1091 if(prfg >= 0 && prbg >= 0) /* set prompt colors */
1092 pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg));
1093 if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */
1094 pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg));
1095 if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */
1096 pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg));
1097 if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */
1098 pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg));
1099 if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */
1100 pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg));
1102 if(pico_usingcolor())
1103 pico_set_normal_color();
1105 return pcolors;
1108 #ifdef _WINDOWS
1113 pico_file_drop(int x, int y, char *filename)
1116 * if current buffer is unchanged
1117 * *or* "new buffer" and no current text
1119 if(((curwp->w_bufp->b_flag & BFCHG) == 0)
1120 || (curwp->w_bufp->b_fname[0] == '\0'
1121 && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep)
1122 && curwp->w_doto == 0)){
1123 register BUFFER *bp = curwp->w_bufp;
1124 char bname[NBUFN];
1126 makename(bname, filename);
1127 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
1128 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1129 strncpy(bp->b_fname, filename, sizeof(bp->b_fname));
1130 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1131 bp->b_flag &= ~BFCHG; /* turn off change bit */
1132 if (readin(filename, 1, 1) == ABORT) {
1133 strncpy(bp->b_bname, "", sizeof(bp->b_bname));
1134 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1135 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
1136 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1139 bp->b_dotp = bp->b_linep;
1140 bp->b_doto = 0;
1142 else{
1143 EML eml;
1145 ifile(filename);
1146 curwp->w_flag |= WFHARD;
1147 update();
1148 eml.s = filename;
1149 emlwrite("Inserted dropped file \"%s\"", &eml);
1152 curwp->w_flag |= WFHARD;
1153 update(); /* restore cursor */
1154 return(1);
1156 #endif
1159 /*----------------------------------------------------------------------
1160 print a few lines of help for command line arguments
1162 Args: none
1164 Result: prints help messages
1165 ----------------------------------------------------------------------*/
1166 void
1167 pico_args_help(void)
1169 char **a;
1170 char *pp[2];
1172 pp[1] = NULL;
1174 /** print out possible starting arguments... **/
1176 for(a=args_pico_args; a && *a; a++){
1177 pp[0] = _(*a);
1178 pico_display_args_err(NULL, pp, 0);
1181 exit(1);
1185 void
1186 pico_vers_help(void)
1188 char v0[100];
1189 char *v[2];
1191 snprintf(v0, sizeof(v0), "Pico %.50s", version);
1192 v[0] = v0;
1193 v[1] = NULL;
1195 pico_display_args_err(NULL, v, 0);
1196 exit(1);
1200 /*----------------------------------------------------------------------
1201 write argument error to the display...
1203 Args: none
1205 Result: prints help messages
1206 ----------------------------------------------------------------------*/
1207 void
1208 pico_display_args_err(char *s, char **a, int err)
1210 char errstr[256], *errp;
1211 FILE *fp = err ? stderr : stdout;
1212 #ifdef _WINDOWS
1213 char tmp_20k_buf[SIZEOF_20KBUF];
1214 #endif
1217 if(err && s)
1218 snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
1219 else
1220 errp = s;
1222 #ifdef _WINDOWS
1223 if(errp)
1224 mswin_messagebox(errp, err);
1226 if(a && *a){
1227 strncpy(tmp_20k_buf, *a++, SIZEOF_20KBUF);
1228 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1229 while(a && *a){
1230 strncat(tmp_20k_buf, "\n", SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1231 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1232 strncat(tmp_20k_buf, *a++, SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1233 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1236 mswin_messagebox(tmp_20k_buf, err);
1238 #else
1239 if(errp)
1240 fprintf(fp, "%s\n", errp);
1242 while(a && *a)
1243 fprintf(fp, "%s\n", *a++);
1244 #endif