~ubuntu-branches/debian/squeeze/alpine/squeeze

« back to all changes in this revision

Viewing changes to alpine/osdep/termout.gen.c

  • Committer: Bazaar Package Importer
  • Author(s): Asheesh Laroia
  • Date: 2007-02-17 13:17:42 UTC
  • Revision ID: james.westby@ubuntu.com-20070217131742-99x5c6cpg1pbkdhw
Tags: upstream-0.82+dfsg
ImportĀ upstreamĀ versionĀ 0.82+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if !defined(lint) && !defined(DOS)
 
2
static char rcsid[] = "$Id: termout.gen.c 380 2007-01-23 00:09:18Z hubert@u.washington.edu $";
 
3
#endif
 
4
 
 
5
/*
 
6
 * ========================================================================
 
7
 * Copyright 2006-2007 University of Washington
 
8
 *
 
9
 * Licensed under the Apache License, Version 2.0 (the "License");
 
10
 * you may not use this file except in compliance with the License.
 
11
 * You may obtain a copy of the License at
 
12
 *
 
13
 *     http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 * ========================================================================
 
16
 */
 
17
#include <system.h>
 
18
#include <general.h>
 
19
 
 
20
#include "../../c-client/mail.h"        /* for MAILSTREAM and friends */
 
21
#include "../../c-client/osdep.h"
 
22
#include "../../c-client/rfc822.h"      /* for soutr_t and such */
 
23
#include "../../c-client/misc.h"        /* for cpystr proto */
 
24
#include "../../c-client/utf8.h"        /* for CHARSET and such*/
 
25
#include "../../c-client/imap4r1.h"
 
26
 
 
27
#include "../../pith/osdep/color.h"
 
28
#include "../../pith/charconv/filesys.h"
 
29
 
 
30
#include "../../pith/debug.h"
 
31
#include "../../pith/newmail.h"
 
32
#include "../../pith/filter.h"
 
33
#include "../../pith/handle.h"
 
34
#include "../../pith/conf.h"
 
35
 
 
36
#include "../../pico/estruct.h"
 
37
#include "../../pico/pico.h"
 
38
#include "../../pico/keydefs.h"
 
39
 
 
40
#include "../status.h"
 
41
#include "../radio.h"
 
42
#include "../folder.h"
 
43
#include "../keymenu.h"
 
44
#include "../send.h"
 
45
 
 
46
#include "termout.gen.h"
 
47
 
 
48
 
 
49
#define PUTLINE_BUFLEN  256
 
50
 
 
51
 
 
52
int   _line  = FARAWAY;
 
53
int   _col   = FARAWAY;
 
54
 
 
55
/*
 
56
 * Generic tty output routines...
 
57
 */
 
58
 
 
59
/*----------------------------------------------------------------------
 
60
      Printf style output line to the screen at given position, 0 args
 
61
 
 
62
  Args:  x -- column position on the screen
 
63
         y -- row position on the screen
 
64
         line -- line of text to output
 
65
 
 
66
 Result: text is output
 
67
         cursor position is update
 
68
  ----*/
 
69
void
 
70
PutLine0(int x, int y, register char *line)
 
71
{
 
72
    MoveCursor(x,y);
 
73
    Write_to_screen(line);
 
74
}
 
75
 
 
76
 
 
77
 
 
78
/*----------------------------------------------------------------------
 
79
  Output line of length len to the display observing embedded attributes
 
80
 
 
81
 Args:  x      -- column position on the screen
 
82
        y      -- column position on the screen
 
83
        line   -- text to be output
 
84
        length -- length of text to be output
 
85
 
 
86
 Result: text is output
 
87
         cursor position is updated
 
88
  ----------------------------------------------------------------------*/
 
89
void
 
90
PutLine0n8b(int x, int y, register char *line, int length, HANDLE_S *handles)
 
91
{
 
92
    unsigned char c;
 
93
    int is_inv = 0, is_bold = 0, is_uline = 0, is_fg = 0, is_bg = 0;
 
94
#ifdef  _WINDOWS
 
95
    int hkey = 0;
 
96
#endif
 
97
 
 
98
    MoveCursor(x,y);
 
99
 
 
100
    while(length--){
 
101
 
 
102
        c = (unsigned char) *line++;
 
103
 
 
104
        if(c == (unsigned char) TAG_EMBED && length){
 
105
 
 
106
            length--;
 
107
 
 
108
            switch(*line++){
 
109
              case TAG_INVON :
 
110
                StartInverse();
 
111
                is_inv = 1;
 
112
                break;
 
113
 
 
114
              case TAG_INVOFF :
 
115
                EndInverse();
 
116
                is_inv = 0;
 
117
                break;
 
118
 
 
119
              case TAG_BOLDON :
 
120
                StartBold();
 
121
                is_bold = 1;
 
122
                break;
 
123
 
 
124
              case TAG_BOLDOFF :
 
125
                EndBold();
 
126
                is_bold = 0;
 
127
                break;
 
128
 
 
129
              case TAG_ITALICON : /* express italic as uline in terminal */
 
130
              case TAG_ULINEON :
 
131
                StartUnderline();
 
132
                is_uline = 1;
 
133
                break;
 
134
 
 
135
              case TAG_ITALICOFF : /* express italic as uline in terminal */
 
136
              case TAG_ULINEOFF :
 
137
                EndUnderline();
 
138
                is_uline = 0;
 
139
                break;
 
140
 
 
141
              case TAG_HANDLE :
 
142
                length -= *line + 1;    /* key length plus length tag */
 
143
                if(handles){
 
144
                    int  key, n, current_key = 0;
 
145
 
 
146
                    for(key = 0, n = *line++; n; n--) /* forget Horner? */
 
147
                      key = (key * 10) + (*line++ - '0');
 
148
 
 
149
#if     _WINDOWS
 
150
                    hkey = key;
 
151
#endif
 
152
 
 
153
                    if(handles->using_is_used){
 
154
                        HANDLE_S *h;
 
155
 
 
156
                        for(h = handles; h; h = h->next)
 
157
                          if(h->is_used)
 
158
                            break;
 
159
                        
 
160
                        if(h)
 
161
                          current_key = h->key;
 
162
                    }
 
163
                    else
 
164
                      current_key = handles->key;
 
165
 
 
166
                    if(key == current_key){
 
167
                        if(pico_usingcolor() &&
 
168
                           ps_global->VAR_SLCTBL_FORE_COLOR &&
 
169
                           ps_global->VAR_SLCTBL_BACK_COLOR){
 
170
                            pico_set_normal_color();
 
171
                        }
 
172
                        else
 
173
                          EndBold();
 
174
 
 
175
                        StartInverse();
 
176
                        is_inv = 1;
 
177
                    }
 
178
                }
 
179
                else{
 
180
                    /* BUG: complain? */
 
181
                    line += *line + 1;
 
182
                }
 
183
 
 
184
                break;
 
185
 
 
186
              case TAG_FGCOLOR :
 
187
                if(length < RGBLEN){
 
188
                    dprint((9,
 
189
                               "FGCOLOR not proper length, ignoring\n"));
 
190
                    length = 0;
 
191
                    break;
 
192
                }
 
193
 
 
194
                (void)pico_set_fg_color(line);
 
195
                is_fg = 1;
 
196
                length -= RGBLEN;
 
197
                line += RGBLEN;
 
198
                break;
 
199
 
 
200
              case TAG_BGCOLOR :
 
201
                if(length < RGBLEN){
 
202
                    dprint((9,
 
203
                               "BGCOLOR not proper length, ignoring\n"));
 
204
                    length = 0;
 
205
                    break;
 
206
                }
 
207
 
 
208
                (void)pico_set_bg_color(line);
 
209
                is_bg = 1;
 
210
                length -= RGBLEN;
 
211
                line += RGBLEN;
 
212
                break;
 
213
 
 
214
              case TAG_EMBED:                   /* literal "embed" char */
 
215
                Writechar(TAG_EMBED, 0);
 
216
                break;
 
217
 
 
218
              case TAG_STRIKEON :               /* unsupported text markup */
 
219
              case TAG_STRIKEOFF :
 
220
              case TAG_BIGON :
 
221
              case TAG_BIGOFF :
 
222
              case TAG_SMALLON :
 
223
              case TAG_SMALLOFF :
 
224
              default :                         /* Eat unrecognized tag - TAG_BIGON, etc */
 
225
                break;
 
226
            }                                   /* tag with handle, skip it */
 
227
        }       
 
228
        else
 
229
          Writechar(c, 0);
 
230
    }
 
231
 
 
232
 
 
233
#if     _WINDOWS_X
 
234
    if(hkey) {
 
235
        char *tmp_file = NULL, ext[32], mtype[128];
 
236
        HANDLE_S *h;
 
237
        extern HANDLE_S *get_handle (HANDLE_S *, int);
 
238
 
 
239
        if((h = get_handle(handles, hkey)) && h->type == Attach){
 
240
            ext[0] = '\0';
 
241
            strncpy(mtype, body_type_names(h->h.attach->body->type), sizeof(mtype));
 
242
            mtype[sizeof(mtype)-1] = '\0';
 
243
            if (h->h.attach->body->subtype) {
 
244
                strncat (mtype, "/", sizeof(mtype)-strlen(mtype));
 
245
                mtype[sizeof(mtype)-1] = '\0';
 
246
                strncat (mtype, h->h.attach->body->subtype, sizeof(mtype)-strlen(mtype));
 
247
                mtype[sizeof(mtype)-1] = '\0';
 
248
            }
 
249
 
 
250
            if(!set_mime_extension_by_type(ext, mtype)){
 
251
                char *namep, *dotp, *p;
 
252
 
 
253
                if(namep = rfc2231_get_param(h->h.attach->body->parameter,
 
254
                                             "name", NULL, NULL)){
 
255
                    for(dotp = NULL, p = namep; *p; p++)
 
256
                      if(*p == '.')
 
257
                        dotp = p + 1;
 
258
 
 
259
                    if(dotp && strlen(dotp) < sizeof(ext) - 1){
 
260
                        strncpy(ext, dotp, sizeof(ext));
 
261
                        ext[sizeof(ext)-1] = '\0';
 
262
                    }
 
263
 
 
264
                    fs_give((void **) &namep);
 
265
                }
 
266
            }
 
267
 
 
268
            if(ext[0] && (tmp_file = temp_nam_ext(NULL, "im", 0, ext))){
 
269
                FILE *f = our_fopen(tmp_file, "w");
 
270
 
 
271
                mswin_registericon(x, h->key, tmp_file);
 
272
 
 
273
                fclose(f);
 
274
                our_unlink(tmp_file);
 
275
                fs_give((void **)&tmp_file);
 
276
            }
 
277
        }
 
278
    }
 
279
#endif
 
280
    if(is_inv){
 
281
        dprint((9,
 
282
                   "INVERSE left on at end of line, turning off now\n"));
 
283
        EndInverse();
 
284
    }
 
285
    if(is_bold){
 
286
        dprint((9,
 
287
                   "BOLD left on at end of line, turning off now\n"));
 
288
        EndBold();
 
289
    }
 
290
    if(is_uline){
 
291
        dprint((9,
 
292
                   "UNDERLINE left on at end of line, turning off now\n"));
 
293
        EndUnderline();
 
294
    }
 
295
    if(is_fg || is_bg)
 
296
      pico_set_normal_color();
 
297
 
 
298
}
 
299
 
 
300
 
 
301
/*----------------------------------------------------------------------
 
302
      Printf style output line to the screen at given position, 1 arg
 
303
 
 
304
 Input:  position on the screen
 
305
         line of text to output
 
306
 
 
307
 Result: text is output
 
308
         cursor position is update
 
309
  ----------------------------------------------------------------------*/
 
310
void
 
311
/*VARARGS2*/
 
312
PutLine1(int x, int y, char *line, void *arg1)
 
313
{
 
314
    char buffer[PUTLINE_BUFLEN];
 
315
 
 
316
    snprintf(buffer, sizeof(buffer), line, arg1);
 
317
    buffer[sizeof(buffer)-1] = '\0';
 
318
    PutLine0(x, y, buffer);
 
319
}
 
320
 
 
321
 
 
322
/*----------------------------------------------------------------------
 
323
      Printf style output line to the screen at given position, 2 args
 
324
 
 
325
 Input:  position on the screen
 
326
         line of text to output
 
327
 
 
328
 Result: text is output
 
329
         cursor position is update
 
330
  ----------------------------------------------------------------------*/
 
331
void
 
332
/*VARARGS3*/
 
333
PutLine2(int x, int y, char *line, void *arg1, void *arg2)
 
334
{
 
335
    char buffer[PUTLINE_BUFLEN];
 
336
 
 
337
    snprintf(buffer, sizeof(buffer), line, arg1, arg2);
 
338
    buffer[sizeof(buffer)-1] = '\0';
 
339
    PutLine0(x, y, buffer);
 
340
}
 
341
 
 
342
 
 
343
/*----------------------------------------------------------------------
 
344
      Printf style output line to the screen at given position, 3 args
 
345
 
 
346
 Input:  position on the screen
 
347
         line of text to output
 
348
 
 
349
 Result: text is output
 
350
         cursor position is update
 
351
  ----------------------------------------------------------------------*/
 
352
void
 
353
/*VARARGS4*/
 
354
PutLine3(int x, int y, char *line, void *arg1, void *arg2, void *arg3)
 
355
{
 
356
    char buffer[PUTLINE_BUFLEN];
 
357
 
 
358
    snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3);
 
359
    buffer[sizeof(buffer)-1] = '\0';
 
360
    PutLine0(x, y, buffer);
 
361
}
 
362
 
 
363
 
 
364
/*----------------------------------------------------------------------
 
365
      Printf style output line to the screen at given position, 4 args
 
366
 
 
367
 Args:  x -- column position on the screen
 
368
        y -- column position on the screen
 
369
        line -- printf style line of text to output
 
370
 
 
371
 Result: text is output
 
372
         cursor position is update
 
373
  ----------------------------------------------------------------------*/
 
374
void
 
375
/*VARARGS5*/
 
376
PutLine4(int x, int y, char *line, void *arg1, void *arg2, void *arg3, void *arg4)
 
377
{
 
378
    char buffer[PUTLINE_BUFLEN];
 
379
 
 
380
    snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3, arg4);
 
381
    buffer[sizeof(buffer)-1] = '\0';
 
382
    PutLine0(x, y, buffer);
 
383
}
 
384
 
 
385
 
 
386
 
 
387
/*----------------------------------------------------------------------
 
388
      Printf style output line to the screen at given position, 5 args
 
389
 
 
390
 Args:  x -- column position on the screen
 
391
        y -- column position on the screen
 
392
        line -- printf style line of text to output
 
393
 
 
394
 Result: text is output
 
395
         cursor position is update
 
396
  ----------------------------------------------------------------------*/
 
397
void
 
398
/*VARARGS6*/
 
399
PutLine5(int x, int y, char *line, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5)
 
400
{
 
401
    char buffer[PUTLINE_BUFLEN];
 
402
 
 
403
    snprintf(buffer, sizeof(buffer), line, arg1, arg2, arg3, arg4, arg5);
 
404
    buffer[sizeof(buffer)-1] = '\0';
 
405
    PutLine0(x, y, buffer);
 
406
}
 
407
 
 
408
 
 
409
/*----------------------------------------------------------------------
 
410
       Output a UTF-8 line to the screen, centered
 
411
 
 
412
  Input:  Line number to print on, string to output
 
413
  
 
414
 Result:  String is output to screen
 
415
          Returns column number line is output on
 
416
  ----------------------------------------------------------------------*/
 
417
int
 
418
Centerline(int line, char *string)
 
419
{
 
420
    int width, col;
 
421
 
 
422
    width = (int) utf8_width(string);
 
423
 
 
424
    if (width > ps_global->ttyo->screen_cols)
 
425
      col = 0;
 
426
    else
 
427
      col = (ps_global->ttyo->screen_cols - width) / 2;
 
428
 
 
429
    PutLine0(line, col, string);
 
430
 
 
431
    return(col);
 
432
}
 
433
 
 
434
 
 
435
 
 
436
/*----------------------------------------------------------------------
 
437
     Clear specified line on the screen
 
438
 
 
439
 Result: The line is blanked and the cursor is left at column 0.
 
440
 
 
441
  ----*/
 
442
void
 
443
ClearLine(int n)
 
444
{
 
445
    if(ps_global->in_init_seq)
 
446
      return;
 
447
 
 
448
    MoveCursor(n, 0);
 
449
    CleartoEOLN();
 
450
}
 
451
 
 
452
 
 
453
 
 
454
/*----------------------------------------------------------------------
 
455
     Clear specified lines on the screen
 
456
 
 
457
 Result: The lines starting at 'x' and ending at 'y' are blanked
 
458
         and the cursor is left at row 'x', column 0
 
459
 
 
460
  ----*/
 
461
void
 
462
ClearLines(int x, int y)
 
463
{
 
464
    int i;
 
465
 
 
466
    for(i = x; i <= y; i++)
 
467
      ClearLine(i);
 
468
 
 
469
    MoveCursor(x, 0);
 
470
}
 
471
 
 
472
 
 
473
 
 
474
/*----------------------------------------------------------------------
 
475
    Indicate to the screen painting here that the position of the cursor
 
476
 has been disturbed and isn't where these functions might think.
 
477
 ----*/
 
478
void
 
479
clear_cursor_pos(void)
 
480
{
 
481
    _line = FARAWAY;
 
482
    _col  = FARAWAY;
 
483
}
 
484
 
 
485
 
 
486
/*----------------------------------------------------------------------
 
487
    Write a character to the screen, keeping track of cursor position
 
488
 
 
489
   Args: ch -- character to output. The stream of characters coming to
 
490
               this function is expected to be UTF-8. State is kept  between
 
491
               calls in order to collect up the octets needed for a single
 
492
               Unicode character.
 
493
 
 
494
 Result: character output
 
495
         cursor position variables updated
 
496
  ----*/
 
497
void
 
498
Writechar(register unsigned int ch, int new_esc_len)
 
499
{
 
500
    static   unsigned char  cbuf[6];
 
501
    static   unsigned char *cbufp = cbuf;
 
502
    int printable_ascii = 0;
 
503
 
 
504
    if(cbufp < cbuf+sizeof(cbuf)){
 
505
        unsigned char *inputp;
 
506
        unsigned long remaining_octets;
 
507
        UCS ucs;
 
508
 
 
509
        *cbufp++ = (unsigned char) ch;
 
510
        inputp = cbuf;
 
511
        remaining_octets = (cbufp - cbuf) * sizeof(unsigned char);
 
512
        if(remaining_octets == 1 && isascii(*cbuf)
 
513
           && (isprint(*cbuf) || *cbuf == LINE_FEED
 
514
               || *cbuf == RETURN || *cbuf == BACKSPACE
 
515
               || *cbuf == BELL || *cbuf == TAB)){
 
516
            /* shortcut common case */
 
517
            ucs = (UCS) *cbuf;
 
518
            inputp++;
 
519
            printable_ascii++;          /* just for efficiency */
 
520
        }
 
521
        else
 
522
          /*
 
523
           * we could use mbtow(utf8_charset, ...)
 
524
           * here to lend an air of portability, then use the CCONV_
 
525
           * constants for the return values. However, we know we are
 
526
           * dealing with UTF-8 so we can skip straight to the
 
527
           * correct function instead.
 
528
           */
 
529
          ucs = (UCS) utf8_get(&inputp, &remaining_octets);
 
530
 
 
531
        switch(ucs){
 
532
          case U8G_BADCONT:     /* continuation at start of char */
 
533
          case U8G_NOTUTF8:     /* invalid character */
 
534
          case U8G_INCMPLT:     /* incomplete character */
 
535
          case UBOGON:
 
536
            /*
 
537
             * None of these cases is supposed to happen. If it
 
538
             * does happen then the input stream isn't UTF-8
 
539
             * so something is wrong. Treat each character in the
 
540
             * input buffer as a separate error character and
 
541
             * print a '?' for each.
 
542
             */
 
543
            for(inputp = cbuf; inputp < cbufp; inputp++){
 
544
                int width = 0;
 
545
 
 
546
                if(_col + width < ps_global->ttyo->screen_cols){
 
547
                    Writewchar('?');
 
548
                    width++;
 
549
                }
 
550
            }
 
551
 
 
552
            cbufp = cbuf;       /* start over */
 
553
            break;
 
554
 
 
555
          case U8G_ENDSTRG:     /* incomplete character, wait */
 
556
          case U8G_ENDSTRI:     /* incomplete character, wait */
 
557
            break;
 
558
 
 
559
          default:
 
560
            /* got a character */
 
561
            Writewchar(ucs);
 
562
 
 
563
            /* update the input buffer */
 
564
            if(inputp >= cbufp) /* this should be the case */
 
565
              cbufp = cbuf;
 
566
            else{               /* extra chars for some reason? */
 
567
                unsigned char *q, *newcbufp;
 
568
 
 
569
                newcbufp = (cbufp - inputp) + cbuf;
 
570
                q = cbuf;
 
571
                while(inputp < cbufp)
 
572
                  *q++ = *inputp++;
 
573
 
 
574
                cbufp = newcbufp;
 
575
            }
 
576
 
 
577
            break;
 
578
        }
 
579
    }
 
580
    else                        /* error */
 
581
      Writewchar('?');
 
582
}