* New version 2.20.11
[alpine.git] / alpine / osdep / termout.gen.c
blob1cded4381af9652238358518f71e559ad53d2a18
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: termout.gen.c 1012 2008-03-26 00:44:22Z 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 * ========================================================================
18 #include <system.h>
19 #include <general.h>
21 #include "../../c-client/mail.h" /* for MAILSTREAM and friends */
22 #include "../../c-client/osdep.h"
23 #include "../../c-client/rfc822.h" /* for soutr_t and such */
24 #include "../../c-client/misc.h" /* for cpystr proto */
25 #include "../../c-client/utf8.h" /* for CHARSET and such*/
26 #include "../../c-client/imap4r1.h"
28 #include "../../pith/osdep/color.h"
29 #include "../../pith/charconv/filesys.h"
31 #include "../../pith/debug.h"
32 #include "../../pith/newmail.h"
33 #include "../../pith/filter.h"
34 #include "../../pith/handle.h"
35 #include "../../pith/conf.h"
36 #include "../../pith/mimedesc.h"
38 #include "../../pico/estruct.h"
39 #include "../../pico/pico.h"
40 #include "../../pico/keydefs.h"
41 #include "../../pico/osdep/color.h"
43 #include "../status.h"
44 #include "../radio.h"
45 #include "../folder.h"
46 #include "../keymenu.h"
47 #include "../send.h"
48 #include "../mailindx.h"
50 int _line = FARAWAY;
51 int _col = FARAWAY;
53 #include "termout.gen.h"
56 #define PUTLINE_BUFLEN 256
61 * Generic tty output routines...
64 /*----------------------------------------------------------------------
65 Printf style output line to the screen at given position, 0 args
67 Args: x -- column position on the screen
68 y -- row position on the screen
69 line -- line of text to output
71 Result: text is output
72 cursor position is update
73 ----*/
74 void
75 PutLine0(int x, int y, register char *line)
77 MoveCursor(x,y);
78 Write_to_screen(line);
83 /*----------------------------------------------------------------------
84 Output line of length len to the display observing embedded attributes
86 Args: x -- column position on the screen
87 y -- column position on the screen
88 line -- text to be output
89 length -- length of text to be output
91 Result: text is output
92 cursor position is updated
93 ----------------------------------------------------------------------*/
94 void
95 PutLine0n8b(int x, int y, register char *line, int length, HANDLE_S *handles)
97 unsigned char c;
98 int is_inv = 0, is_bold = 0, is_uline = 0, is_fg = 0, is_bg = 0;
99 #ifdef _WINDOWS
100 int hkey = 0;
101 #endif
103 MoveCursor(x,y);
105 while(length--){
107 c = (unsigned char) *line++;
109 if(c == (unsigned char) TAG_EMBED && length){
111 length--;
113 switch(*line++){
114 case TAG_INVON :
115 StartInverse();
116 is_inv = 1;
117 break;
119 case TAG_INVOFF :
120 EndInverse();
121 is_inv = 0;
122 break;
124 case TAG_BOLDON :
125 StartBold();
126 is_bold = 1;
127 break;
129 case TAG_BOLDOFF :
130 EndBold();
131 is_bold = 0;
132 break;
134 case TAG_ITALICON : /* express italic as uline in terminal */
135 case TAG_ULINEON :
136 StartUnderline();
137 is_uline = 1;
138 break;
140 case TAG_ITALICOFF : /* express italic as uline in terminal */
141 case TAG_ULINEOFF :
142 EndUnderline();
143 is_uline = 0;
144 break;
146 case TAG_HANDLE :
147 length -= *line + 1; /* key length plus length tag */
148 if(handles){
149 int key, n, current_key = 0;
151 for(key = 0, n = *line++; n; n--) /* forget Horner? */
152 key = (key * 10) + (*line++ - '0');
154 #if _WINDOWS
155 hkey = key;
156 #endif
158 if(handles->using_is_used){
159 HANDLE_S *h;
161 for(h = handles; h; h = h->next)
162 if(h->is_used)
163 break;
165 if(h)
166 current_key = h->key;
168 else
169 current_key = handles->key;
171 if(key == current_key){
172 COLOR_PAIR *curcolor = NULL;
173 COLOR_PAIR *revcolor = NULL;
175 if(handles->color_unseen
176 && (curcolor = pico_get_cur_color())
177 && (colorcmp(curcolor->fg, ps_global->VAR_NORM_FORE_COLOR)
178 || colorcmp(curcolor->bg, ps_global->VAR_NORM_BACK_COLOR))
179 && (revcolor = apply_rev_color(curcolor,
180 ps_global->index_color_style)))
181 (void) pico_set_colorp(revcolor, PSC_NONE);
182 else{
184 if(pico_usingcolor() &&
185 ps_global->VAR_SLCTBL_FORE_COLOR &&
186 ps_global->VAR_SLCTBL_BACK_COLOR){
187 pico_set_normal_color();
189 else
190 EndBold();
192 StartInverse();
193 is_inv = 1;
196 if(curcolor)
197 free_color_pair(&curcolor);
199 if(revcolor)
200 free_color_pair(&revcolor);
203 else{
204 /* BUG: complain? */
205 line += *line + 1;
208 break;
210 case TAG_FGCOLOR :
211 if(length < RGBLEN){
212 dprint((9,
213 "FGCOLOR not proper length, ignoring\n"));
214 length = 0;
215 break;
218 (void)pico_set_fg_color(line);
219 is_fg = 1;
220 length -= RGBLEN;
221 line += RGBLEN;
222 break;
224 case TAG_BGCOLOR :
225 if(length < RGBLEN){
226 dprint((9,
227 "BGCOLOR not proper length, ignoring\n"));
228 length = 0;
229 break;
232 (void)pico_set_bg_color(line);
233 is_bg = 1;
234 length -= RGBLEN;
235 line += RGBLEN;
236 break;
238 case TAG_EMBED: /* literal "embed" char */
239 Writechar(TAG_EMBED, 0);
240 break;
242 case TAG_STRIKEON : /* unsupported text markup */
243 case TAG_STRIKEOFF :
244 case TAG_BIGON :
245 case TAG_BIGOFF :
246 case TAG_SMALLON :
247 case TAG_SMALLOFF :
248 default : /* Eat unrecognized tag - TAG_BIGON, etc */
249 break;
250 } /* tag with handle, skip it */
252 else
253 Writechar(c, 0);
257 #if _WINDOWS_X
258 if(hkey) {
259 char *tmp_file = NULL, ext[32], mtype[128];
260 HANDLE_S *h;
261 extern HANDLE_S *get_handle (HANDLE_S *, int);
263 if((h = get_handle(handles, hkey)) && h->type == Attach){
264 ext[0] = '\0';
265 strncpy(mtype, body_type_names(h->h.attach->body->type), sizeof(mtype));
266 mtype[sizeof(mtype)-1] = '\0';
267 if (h->h.attach->body->subtype) {
268 strncat (mtype, "/", sizeof(mtype)-strlen(mtype)-1);
269 mtype[sizeof(mtype)-1] = '\0';
270 strncat (mtype, h->h.attach->body->subtype, sizeof(mtype)-strlen(mtype)-1);
271 mtype[sizeof(mtype)-1] = '\0';
274 if(!set_mime_extension_by_type(ext, mtype)){
275 char *p, *extp = NULL;
277 if((p = get_filename_parameter(NULL, 0, h->h.attach->body, &extp)) != NULL){
278 if(extp){
279 strncpy(ext, extp, sizeof(ext));
280 ext[sizeof(ext)-1] = '\0';
283 fs_give((void **) &p);
287 if(ext[0] && (tmp_file = temp_nam_ext(NULL, "im", ext))){
288 FILE *f = our_fopen(tmp_file, "w");
290 mswin_registericon(x, h->key, tmp_file);
292 fclose(f);
293 our_unlink(tmp_file);
294 fs_give((void **)&tmp_file);
298 #endif
299 if(is_inv){
300 dprint((9,
301 "INVERSE left on at end of line, turning off now\n"));
302 EndInverse();
304 if(is_bold){
305 dprint((9,
306 "BOLD left on at end of line, turning off now\n"));
307 EndBold();
309 if(is_uline){
310 dprint((9,
311 "UNDERLINE left on at end of line, turning off now\n"));
312 EndUnderline();
314 if(is_fg || is_bg)
315 pico_set_normal_color();
320 /*----------------------------------------------------------------------
321 Printf style output line to the screen at given position, 1 arg
323 Input: position on the screen
324 line of text to output
326 Result: text is output
327 cursor position is update
328 ----------------------------------------------------------------------*/
329 void
330 /*VARARGS2*/
331 PutLine1(int x, int y, char *line, void *arg1)
333 char buffer[PUTLINE_BUFLEN];
335 snprintf(buffer, sizeof(buffer), line, arg1);
336 buffer[sizeof(buffer)-1] = '\0';
337 PutLine0(x, y, buffer);
341 /*----------------------------------------------------------------------
342 Printf style output line to the screen at given position, 2 args
344 Input: position on the screen
345 line of text to output
347 Result: text is output
348 cursor position is update
349 ----------------------------------------------------------------------*/
350 void
351 /*VARARGS3*/
352 PutLine2(int x, int y, char *line, void *arg1, void *arg2)
354 char buffer[PUTLINE_BUFLEN];
356 snprintf(buffer, sizeof(buffer), line, arg1, arg2);
357 buffer[sizeof(buffer)-1] = '\0';
358 PutLine0(x, y, buffer);
362 /*----------------------------------------------------------------------
363 Printf style output line to the screen at given position, 3 args
365 Input: position on the screen
366 line of text to output
368 Result: text is output
369 cursor position is update
370 ----------------------------------------------------------------------*/
371 void
372 /*VARARGS4*/
373 PutLine3(int x, int y, char *line, void *arg1, void *arg2, void *arg3)
375 char buffer[PUTLINE_BUFLEN];
377 snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3);
378 buffer[sizeof(buffer)-1] = '\0';
379 PutLine0(x, y, buffer);
383 /*----------------------------------------------------------------------
384 Printf style output line to the screen at given position, 4 args
386 Args: x -- column position on the screen
387 y -- column position on the screen
388 line -- printf style line of text to output
390 Result: text is output
391 cursor position is update
392 ----------------------------------------------------------------------*/
393 void
394 /*VARARGS5*/
395 PutLine4(int x, int y, char *line, void *arg1, void *arg2, void *arg3, void *arg4)
397 char buffer[PUTLINE_BUFLEN];
399 snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3, arg4);
400 buffer[sizeof(buffer)-1] = '\0';
401 PutLine0(x, y, buffer);
406 /*----------------------------------------------------------------------
407 Printf style output line to the screen at given position, 5 args
409 Args: x -- column position on the screen
410 y -- column position on the screen
411 line -- printf style line of text to output
413 Result: text is output
414 cursor position is update
415 ----------------------------------------------------------------------*/
416 void
417 /*VARARGS6*/
418 PutLine5(int x, int y, char *line, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5)
420 char buffer[PUTLINE_BUFLEN];
422 snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3, arg4, arg5);
423 buffer[sizeof(buffer)-1] = '\0';
424 PutLine0(x, y, buffer);
428 /*----------------------------------------------------------------------
429 Output a UTF-8 line to the screen, centered
431 Input: Line number to print on, string to output
433 Result: String is output to screen
434 Returns column number line is output on
435 ----------------------------------------------------------------------*/
437 Centerline(int line, char *string)
439 int width, col;
441 width = (int) utf8_width(string);
443 if (width > ps_global->ttyo->screen_cols)
444 col = 0;
445 else
446 col = (ps_global->ttyo->screen_cols - width) / 2;
448 PutLine0(line, col, string);
450 return(col);
455 /*----------------------------------------------------------------------
456 Clear specified line on the screen
458 Result: The line is blanked and the cursor is left at column 0.
460 ----*/
461 void
462 ClearLine(int n)
464 if(ps_global->in_init_seq)
465 return;
467 MoveCursor(n, 0);
468 CleartoEOLN();
473 /*----------------------------------------------------------------------
474 Clear specified lines on the screen
476 Result: The lines starting at 'x' and ending at 'y' are blanked
477 and the cursor is left at row 'x', column 0
479 ----*/
480 void
481 ClearLines(int x, int y)
483 int i;
485 for(i = x; i <= y; i++)
486 ClearLine(i);
488 MoveCursor(x, 0);
493 /*----------------------------------------------------------------------
494 Indicate to the screen painting here that the position of the cursor
495 has been disturbed and isn't where these functions might think.
496 ----*/
497 void
498 clear_cursor_pos(void)
500 _line = FARAWAY;
501 _col = FARAWAY;
505 /*----------------------------------------------------------------------
506 Write a character to the screen, keeping track of cursor position
508 Args: ch -- character to output. The stream of characters coming to
509 this function is expected to be UTF-8. State is kept between
510 calls in order to collect up the octets needed for a single
511 Unicode character.
513 Result: character output
514 cursor position variables updated
515 ----*/
516 void
517 Writechar(unsigned int ch, int new_esc_len)
519 static unsigned char cbuf[6];
520 static unsigned char *cbufp = cbuf;
522 if(cbufp < cbuf+sizeof(cbuf)){
523 unsigned char *inputp;
524 unsigned long remaining_octets;
525 UCS ucs;
527 *cbufp++ = (unsigned char) ch;
528 inputp = cbuf;
529 remaining_octets = (cbufp - cbuf) * sizeof(unsigned char);
530 ucs = (UCS) utf8_get(&inputp, &remaining_octets);
532 switch(ucs){
533 case U8G_ENDSTRG: /* incomplete character, wait */
534 case U8G_ENDSTRI: /* incomplete character, wait */
535 break;
537 default:
538 if(ucs & U8G_ERROR || ucs == UBOGON){
540 * None of these cases is supposed to happen. If it
541 * does happen then the input stream isn't UTF-8
542 * so something is wrong. Treat each character in the
543 * input buffer as a separate error character and
544 * print a '?' for each.
546 for(inputp = cbuf; inputp < cbufp; inputp++){
547 int width = 0;
549 if(_col + width <= ps_global->ttyo->screen_cols){
550 Writewchar('?');
551 width++;
555 cbufp = cbuf; /* start over */
557 else{
559 /* got a good character */
560 Writewchar(ucs);
562 /* update the input buffer */
563 if(inputp >= cbufp) /* this should be the case */
564 cbufp = cbuf;
565 else{ /* extra chars for some reason? */
566 unsigned char *q, *newcbufp;
568 newcbufp = (cbufp - inputp) + cbuf;
569 q = cbuf;
570 while(inputp < cbufp)
571 *q++ = *inputp++;
573 cbufp = newcbufp;
577 break;
580 else{ /* error */
581 Writewchar('?');
582 cbufp = cbuf; /* start over */