~ubuntu-branches/ubuntu/natty/w3m/natty

« back to all changes in this revision

Viewing changes to .pc/080_xhtml-support.patch/display.c

  • Committer: Bazaar Package Importer
  • Author(s): Tatsuya Kinoshita
  • Date: 2010-07-07 00:10:09 UTC
  • mfrom: (3.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100707001009-fku350z06hf0axhz
Tags: 0.5.2-6
* debian/patches/070_form-update.patch: Patch to fix a problem of
  formUpdateBuffer(), from [w3m-dev 04286] on 2007-08-04, provided by
  Hironori SAKAMOTO. (Closes: #409933)
* debian/patches/080_xhtml-support.patch: Patch to support for
  application/xhtml+xml and default UTF-8 encoding, provided by
  Karsten Schoelzel. (Closes: #223589, #242599, #357817)
* debian/patches/090_simple-preserve-space.patch: Patch to add a new
  option "simple_preserve_space", provided by dai.
  (Closes: #384982, #426055)
* debian/patches/*: Renumbered.
* debian/patches/70_ssl-init.patch: Removed.
* debian/w3mconfig: Set ssl_forbid_method to 2 to disable SSLv2.
* debian/copyright: Updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: display.c,v 1.70 2007/05/29 12:07:02 inu Exp $ */
 
2
#include <signal.h>
 
3
#include "fm.h"
 
4
 
 
5
/* *INDENT-OFF* */
 
6
#ifdef USE_COLOR
 
7
 
 
8
#define EFFECT_ANCHOR_START       effect_anchor_start()
 
9
#define EFFECT_ANCHOR_END         effect_anchor_end()
 
10
#define EFFECT_IMAGE_START        effect_image_start()
 
11
#define EFFECT_IMAGE_END          effect_image_end()
 
12
#define EFFECT_FORM_START         effect_form_start()
 
13
#define EFFECT_FORM_END           effect_form_end()
 
14
#define EFFECT_ACTIVE_START       effect_active_start()
 
15
#define EFFECT_ACTIVE_END         effect_active_end()
 
16
#define EFFECT_VISITED_START      effect_visited_start()
 
17
#define EFFECT_VISITED_END        effect_visited_end()
 
18
#define EFFECT_MARK_START         effect_mark_start()
 
19
#define EFFECT_MARK_END           effect_mark_end()
 
20
 
 
21
/*-
 
22
 * color: 
 
23
 *     0  black 
 
24
 *     1  red 
 
25
 *     2  green 
 
26
 *     3  yellow
 
27
 *     4  blue 
 
28
 *     5  magenta 
 
29
 *     6  cyan 
 
30
 *     7  white 
 
31
 */
 
32
 
 
33
#define EFFECT_ANCHOR_START_C       setfcolor(anchor_color)
 
34
#define EFFECT_IMAGE_START_C        setfcolor(image_color)
 
35
#define EFFECT_FORM_START_C         setfcolor(form_color)
 
36
#define EFFECT_ACTIVE_START_C      (setfcolor(active_color), underline())
 
37
#define EFFECT_VISITED_START_C      setfcolor(visited_color)
 
38
#ifdef USE_BG_COLOR
 
39
#define EFFECT_MARK_START_C         setbcolor(mark_color)
 
40
#else
 
41
#define EFFECT_MARK_START_C         standout()
 
42
#endif
 
43
 
 
44
#define EFFECT_IMAGE_END_C          setfcolor(basic_color)
 
45
#define EFFECT_ANCHOR_END_C         setfcolor(basic_color)
 
46
#define EFFECT_FORM_END_C           setfcolor(basic_color)
 
47
#define EFFECT_ACTIVE_END_C        (setfcolor(basic_color), underlineend())
 
48
#define EFFECT_VISITED_END_C        setfcolor(basic_color)
 
49
#ifdef USE_BG_COLOR
 
50
#define EFFECT_MARK_END_C           setbcolor(bg_color)
 
51
#else
 
52
#define EFFECT_MARK_END_C           standend()
 
53
#endif
 
54
 
 
55
#define EFFECT_ANCHOR_START_M       underline()
 
56
#define EFFECT_ANCHOR_END_M         underlineend()
 
57
#define EFFECT_IMAGE_START_M        standout()
 
58
#define EFFECT_IMAGE_END_M          standend()
 
59
#define EFFECT_FORM_START_M         standout()
 
60
#define EFFECT_FORM_END_M           standend()
 
61
#define EFFECT_ACTIVE_START_NC      underline()
 
62
#define EFFECT_ACTIVE_END_NC        underlineend()
 
63
#define EFFECT_ACTIVE_START_M       bold()
 
64
#define EFFECT_ACTIVE_END_M         boldend()
 
65
#define EFFECT_VISITED_START_M /**/
 
66
#define EFFECT_VISITED_END_M /**/
 
67
#define EFFECT_MARK_START_M         standout()
 
68
#define EFFECT_MARK_END_M           standend()
 
69
#define define_effect(name_start,name_end,color_start,color_end,mono_start,mono_end) \
 
70
static void name_start { if (useColor) { color_start; } else { mono_start; }}\
 
71
static void name_end { if (useColor) { color_end; } else { mono_end; }}
 
72
 
 
73
define_effect(EFFECT_ANCHOR_START, EFFECT_ANCHOR_END, EFFECT_ANCHOR_START_C,
 
74
              EFFECT_ANCHOR_END_C, EFFECT_ANCHOR_START_M, EFFECT_ANCHOR_END_M)
 
75
define_effect(EFFECT_IMAGE_START, EFFECT_IMAGE_END, EFFECT_IMAGE_START_C,
 
76
              EFFECT_IMAGE_END_C, EFFECT_IMAGE_START_M, EFFECT_IMAGE_END_M)
 
77
define_effect(EFFECT_FORM_START, EFFECT_FORM_END, EFFECT_FORM_START_C,
 
78
              EFFECT_FORM_END_C, EFFECT_FORM_START_M, EFFECT_FORM_END_M)
 
79
define_effect(EFFECT_MARK_START, EFFECT_MARK_END, EFFECT_MARK_START_C,
 
80
              EFFECT_MARK_END_C, EFFECT_MARK_START_M, EFFECT_MARK_END_M)
 
81
 
 
82
/*****************/
 
83
static void
 
84
EFFECT_ACTIVE_START
 
85
{
 
86
    if (useColor) {
 
87
        if (useActiveColor) {
 
88
#ifdef __EMX__
 
89
            if(!getenv("WINDOWID"))
 
90
                setfcolor(active_color);
 
91
            else
 
92
#endif
 
93
            {
 
94
                EFFECT_ACTIVE_START_C;
 
95
            }
 
96
        } else {
 
97
            EFFECT_ACTIVE_START_NC;
 
98
        }
 
99
    } else {
 
100
        EFFECT_ACTIVE_START_M;
 
101
    }
 
102
}
 
103
 
 
104
static void
 
105
EFFECT_ACTIVE_END
 
106
{
 
107
    if (useColor) {
 
108
        if (useActiveColor) {
 
109
            EFFECT_ACTIVE_END_C;
 
110
        } else {
 
111
            EFFECT_ACTIVE_END_NC;
 
112
        }
 
113
    } else {
 
114
        EFFECT_ACTIVE_END_M;
 
115
    }
 
116
}
 
117
 
 
118
static void
 
119
EFFECT_VISITED_START
 
120
{
 
121
    if (useVisitedColor) {
 
122
        if (useColor) {
 
123
            EFFECT_VISITED_START_C;
 
124
        } else {
 
125
            EFFECT_VISITED_START_M;
 
126
        }
 
127
    }
 
128
}
 
129
 
 
130
static void
 
131
EFFECT_VISITED_END
 
132
{
 
133
    if (useVisitedColor) {
 
134
        if (useColor) {
 
135
            EFFECT_VISITED_END_C;
 
136
        } else {
 
137
            EFFECT_VISITED_END_M;
 
138
        }
 
139
    }
 
140
}
 
141
 
 
142
#else                           /* not USE_COLOR */
 
143
 
 
144
#define EFFECT_ANCHOR_START       underline()
 
145
#define EFFECT_ANCHOR_END         underlineend()
 
146
#define EFFECT_IMAGE_START        standout()
 
147
#define EFFECT_IMAGE_END          standend()
 
148
#define EFFECT_FORM_START         standout()
 
149
#define EFFECT_FORM_END           standend()
 
150
#define EFFECT_ACTIVE_START       bold()
 
151
#define EFFECT_ACTIVE_END         boldend()
 
152
#define EFFECT_VISITED_START /**/
 
153
#define EFFECT_VISITED_END /**/
 
154
#define EFFECT_MARK_START         standout()
 
155
#define EFFECT_MARK_END           standend()
 
156
#endif                          /* not USE_COLOR */
 
157
/* *INDENT-ON* */
 
158
 
 
159
void
 
160
fmTerm(void)
 
161
{
 
162
    if (fmInitialized) {
 
163
        move(LASTLINE, 0);
 
164
        clrtoeolx();
 
165
        refresh();
 
166
#ifdef USE_IMAGE
 
167
        if (activeImage)
 
168
            loadImage(NULL, IMG_FLAG_STOP);
 
169
#endif
 
170
#ifdef USE_MOUSE
 
171
        if (use_mouse)
 
172
            mouse_end();
 
173
#endif                          /* USE_MOUSE */
 
174
        reset_tty();
 
175
        fmInitialized = FALSE;
 
176
    }
 
177
}
 
178
 
 
179
 
 
180
/* 
 
181
 * Initialize routine.
 
182
 */
 
183
void
 
184
fmInit(void)
 
185
{
 
186
    if (!fmInitialized) {
 
187
        initscr();
 
188
        term_raw();
 
189
        term_noecho();
 
190
#ifdef USE_IMAGE
 
191
        if (displayImage)
 
192
            initImage();
 
193
#endif
 
194
    }
 
195
    fmInitialized = TRUE;
 
196
}
 
197
 
 
198
/* 
 
199
 * Display some lines.
 
200
 */
 
201
static Line *cline = NULL;
 
202
static int ccolumn = -1;
 
203
 
 
204
static int ulmode = 0, somode = 0, bomode = 0;
 
205
static int anch_mode = 0, emph_mode = 0, imag_mode = 0, form_mode = 0,
 
206
    active_mode = 0, visited_mode = 0, mark_mode = 0, graph_mode = 0;
 
207
#ifdef USE_ANSI_COLOR
 
208
static Linecolor color_mode = 0;
 
209
#endif
 
210
 
 
211
#ifdef USE_BUFINFO
 
212
static Buffer *save_current_buf = NULL;
 
213
#endif
 
214
 
 
215
static char *delayed_msg = NULL;
 
216
 
 
217
static void drawAnchorCursor(Buffer *buf);
 
218
#define redrawBuffer(buf) redrawNLine(buf, LASTLINE)
 
219
static void redrawNLine(Buffer *buf, int n);
 
220
static Line *redrawLine(Buffer *buf, Line *l, int i);
 
221
#ifdef USE_IMAGE
 
222
static int image_touch = 0;
 
223
static int draw_image_flag = FALSE;
 
224
static Line *redrawLineImage(Buffer *buf, Line *l, int i);
 
225
#endif
 
226
static int redrawLineRegion(Buffer *buf, Line *l, int i, int bpos, int epos);
 
227
static void do_effects(Lineprop m);
 
228
#ifdef USE_ANSI_COLOR
 
229
static void do_color(Linecolor c);
 
230
#endif
 
231
 
 
232
static Str
 
233
make_lastline_link(Buffer *buf, char *title, char *url)
 
234
{
 
235
    Str s = NULL, u;
 
236
#ifdef USE_M17N
 
237
    Lineprop *pr;
 
238
#endif
 
239
    ParsedURL pu;
 
240
    char *p;
 
241
    int l = COLS - 1, i;
 
242
 
 
243
    if (title && *title) {
 
244
        s = Strnew_m_charp("[", title, "]", NULL);
 
245
        for (p = s->ptr; *p; p++) {
 
246
            if (IS_CNTRL(*p) || IS_SPACE(*p))
 
247
                *p = ' ';
 
248
        }
 
249
        if (url)
 
250
            Strcat_charp(s, " ");
 
251
        l -= get_Str_strwidth(s);
 
252
        if (l <= 0)
 
253
            return s;
 
254
    }
 
255
    if (!url)
 
256
        return s;
 
257
    parseURL2(url, &pu, baseURL(buf));
 
258
    u = parsedURL2Str(&pu);
 
259
    if (DecodeURL)
 
260
        u = Strnew_charp(url_unquote_conv(u->ptr, buf->document_charset));
 
261
#ifdef USE_M17N
 
262
    u = checkType(u, &pr, NULL);
 
263
#endif
 
264
    if (l <= 4 || l >= get_Str_strwidth(u)) {
 
265
        if (!s)
 
266
            return u;
 
267
        Strcat(s, u);
 
268
        return s;
 
269
    }
 
270
    if (!s)
 
271
        s = Strnew_size(COLS);
 
272
    i = (l - 2) / 2;
 
273
#ifdef USE_M17N
 
274
    while (i && pr[i] & PC_WCHAR2)
 
275
        i--;
 
276
#endif
 
277
    Strcat_charp_n(s, u->ptr, i);
 
278
    Strcat_charp(s, "..");
 
279
    i = get_Str_strwidth(u) - (COLS - 1 - get_Str_strwidth(s));
 
280
#ifdef USE_M17N
 
281
    while (i < u->length && pr[i] & PC_WCHAR2)
 
282
        i++;
 
283
#endif
 
284
    Strcat_charp(s, &u->ptr[i]);
 
285
    return s;
 
286
}
 
287
 
 
288
static Str
 
289
make_lastline_message(Buffer *buf)
 
290
{
 
291
    Str msg, s = NULL;
 
292
    int sl = 0;
 
293
 
 
294
    if (displayLink) {
 
295
#ifdef USE_IMAGE
 
296
        MapArea *a = retrieveCurrentMapArea(buf);
 
297
        if (a)
 
298
            s = make_lastline_link(buf, a->alt, a->url);
 
299
        else
 
300
#endif
 
301
        {
 
302
            Anchor *a = retrieveCurrentAnchor(buf);
 
303
            char *p = NULL;
 
304
            if (a && a->title && *a->title)
 
305
                p = a->title;
 
306
            else {
 
307
                Anchor *a_img = retrieveCurrentImg(buf);
 
308
                if (a_img && a_img->title && *a_img->title)
 
309
                    p = a_img->title;
 
310
            }
 
311
            if (p || a)
 
312
                s = make_lastline_link(buf, p, a ? a->url : NULL);
 
313
        }
 
314
        if (s) {
 
315
            sl = get_Str_strwidth(s);
 
316
            if (sl >= COLS - 3)
 
317
                return s;
 
318
        }
 
319
    }
 
320
 
 
321
#ifdef USE_MOUSE
 
322
    if (use_mouse && mouse_action.lastline_str)
 
323
        msg = Strnew_charp(mouse_action.lastline_str);
 
324
    else
 
325
#endif                          /* not USE_MOUSE */
 
326
        msg = Strnew();
 
327
    if (displayLineInfo && buf->currentLine != NULL && buf->lastLine != NULL) {
 
328
        int cl = buf->currentLine->real_linenumber;
 
329
        int ll = buf->lastLine->real_linenumber;
 
330
        int r = (int)((double)cl * 100.0 / (double)(ll ? ll : 1) + 0.5);
 
331
        Strcat(msg, Sprintf("%d/%d (%d%%)", cl, ll, r));
 
332
    }
 
333
    else
 
334
        /* FIXME: gettextize? */
 
335
        Strcat_charp(msg, "Viewing");
 
336
#ifdef USE_SSL
 
337
    if (buf->ssl_certificate)
 
338
        Strcat_charp(msg, "[SSL]");
 
339
#endif
 
340
    Strcat_charp(msg, " <");
 
341
    Strcat_charp(msg, buf->buffername);
 
342
 
 
343
    if (s) {
 
344
        int l = COLS - 3 - sl;
 
345
        if (get_Str_strwidth(msg) > l) {
 
346
#ifdef USE_M17N
 
347
            char *p;
 
348
            for (p = msg->ptr; *p; p += get_mclen(p)) {
 
349
                l -= get_mcwidth(p);
 
350
                if (l < 0)
 
351
                    break;
 
352
            }
 
353
            l = p - msg->ptr;
 
354
#endif
 
355
            Strtruncate(msg, l);
 
356
        }
 
357
        Strcat_charp(msg, "> ");
 
358
        Strcat(msg, s);
 
359
    }
 
360
    else {
 
361
        Strcat_charp(msg, ">");
 
362
    }
 
363
    return msg;
 
364
}
 
365
 
 
366
void
 
367
displayBuffer(Buffer *buf, int mode)
 
368
{
 
369
    Str msg;
 
370
    int ny = 0;
 
371
 
 
372
    if (!buf)
 
373
        return;
 
374
    if (buf->topLine == NULL && readBufferCache(buf) == 0) {    /* clear_buffer */
 
375
        mode = B_FORCE_REDRAW;
 
376
    }
 
377
 
 
378
    if (buf->width == 0)
 
379
        buf->width = INIT_BUFFER_WIDTH;
 
380
    if (buf->height == 0)
 
381
        buf->height = LASTLINE + 1;
 
382
    if ((buf->width != INIT_BUFFER_WIDTH &&
 
383
         ((buf->type && !strcmp(buf->type, "text/html")) || FoldLine))
 
384
        || buf->need_reshape) {
 
385
        buf->need_reshape = TRUE;
 
386
        reshapeBuffer(buf);
 
387
    }
 
388
    if (showLineNum) {
 
389
        if (buf->lastLine && buf->lastLine->real_linenumber > 0)
 
390
            buf->rootX = (int)(log(buf->lastLine->real_linenumber + 0.1)
 
391
                               / log(10)) + 2;
 
392
        if (buf->rootX < 5)
 
393
            buf->rootX = 5;
 
394
        if (buf->rootX > COLS)
 
395
            buf->rootX = COLS;
 
396
    }
 
397
    else
 
398
        buf->rootX = 0;
 
399
    buf->COLS = COLS - buf->rootX;
 
400
    if (nTab > 1
 
401
#ifdef USE_MOUSE
 
402
        || mouse_action.menu_str
 
403
#endif
 
404
        ) {
 
405
        if (mode == B_FORCE_REDRAW || mode == B_REDRAW_IMAGE)
 
406
            calcTabPos();
 
407
        ny = LastTab->y + 2;
 
408
        if (ny > LASTLINE)
 
409
            ny = LASTLINE;
 
410
    }
 
411
    if (buf->rootY != ny || buf->LINES != LASTLINE - ny) {
 
412
        buf->rootY = ny;
 
413
        buf->LINES = LASTLINE - ny;
 
414
        arrangeCursor(buf);
 
415
        mode = B_REDRAW_IMAGE;
 
416
    }
 
417
    if (mode == B_FORCE_REDRAW || mode == B_SCROLL || mode == B_REDRAW_IMAGE ||
 
418
        cline != buf->topLine || ccolumn != buf->currentColumn) {
 
419
#ifdef USE_RAW_SCROLL
 
420
        if (
 
421
#ifdef USE_IMAGE
 
422
               !(activeImage && displayImage && draw_image_flag) &&
 
423
#endif
 
424
               mode == B_SCROLL && cline && buf->currentColumn == ccolumn) {
 
425
            int n = buf->topLine->linenumber - cline->linenumber;
 
426
            if (n > 0 && n < buf->LINES) {
 
427
                move(LASTLINE, 0);
 
428
                clrtoeolx();
 
429
                refresh();
 
430
                scroll(n);
 
431
            }
 
432
            else if (n < 0 && n > -buf->LINES) {
 
433
#if 0 /* defined(__CYGWIN__) */
 
434
                move(LASTLINE + n + 1, 0);
 
435
                clrtoeolx();
 
436
                refresh();
 
437
#endif                          /* defined(__CYGWIN__) */
 
438
                rscroll(-n);
 
439
            }
 
440
            redrawNLine(buf, n);
 
441
        }
 
442
        else
 
443
#endif
 
444
        {
 
445
#ifdef USE_IMAGE
 
446
            if (activeImage &&
 
447
                (mode == B_REDRAW_IMAGE ||
 
448
                 cline != buf->topLine || ccolumn != buf->currentColumn)) {
 
449
                if (draw_image_flag)
 
450
                    clear();
 
451
                clearImage();
 
452
                loadImage(buf, IMG_FLAG_STOP);
 
453
                image_touch++;
 
454
                draw_image_flag = FALSE;
 
455
            }
 
456
#endif
 
457
            redrawBuffer(buf);
 
458
        }
 
459
        cline = buf->topLine;
 
460
        ccolumn = buf->currentColumn;
 
461
    }
 
462
    if (buf->topLine == NULL)
 
463
        buf->topLine = buf->firstLine;
 
464
 
 
465
#ifdef USE_IMAGE
 
466
    if (buf->need_reshape) {
 
467
        displayBuffer(buf, B_FORCE_REDRAW);
 
468
        return;
 
469
    }
 
470
#endif
 
471
 
 
472
    drawAnchorCursor(buf);
 
473
 
 
474
    msg = make_lastline_message(buf);
 
475
    if (buf->firstLine == NULL) {
 
476
        /* FIXME: gettextize? */
 
477
        Strcat_charp(msg, "\tNo Line");
 
478
    }
 
479
    if (delayed_msg != NULL) {
 
480
        disp_message(delayed_msg, FALSE);
 
481
        delayed_msg = NULL;
 
482
        refresh();
 
483
    }
 
484
    standout();
 
485
    message(msg->ptr, buf->cursorX + buf->rootX, buf->cursorY + buf->rootY);
 
486
    standend();
 
487
    term_title(conv_to_system(buf->buffername));
 
488
    refresh();
 
489
#ifdef USE_IMAGE
 
490
    if (activeImage && displayImage && buf->img) {
 
491
        drawImage();
 
492
    }
 
493
#endif
 
494
#ifdef USE_BUFINFO
 
495
    if (buf != save_current_buf) {
 
496
        saveBufferInfo();
 
497
        save_current_buf = buf;
 
498
    }
 
499
#endif
 
500
}
 
501
 
 
502
static void
 
503
drawAnchorCursor0(Buffer *buf, AnchorList *al, int hseq, int prevhseq,
 
504
                  int tline, int eline, int active)
 
505
{
 
506
    int i, j;
 
507
    Line *l;
 
508
    Anchor *an;
 
509
 
 
510
    l = buf->topLine;
 
511
    for (j = 0; j < al->nanchor; j++) {
 
512
        an = &al->anchors[j];
 
513
        if (an->start.line < tline)
 
514
            continue;
 
515
        if (an->start.line >= eline)
 
516
            return;
 
517
        for (;; l = l->next) {
 
518
            if (l == NULL)
 
519
                return;
 
520
            if (l->linenumber == an->start.line)
 
521
                break;
 
522
        }
 
523
        if (hseq >= 0 && an->hseq == hseq) {
 
524
            for (i = an->start.pos; i < an->end.pos; i++) {
 
525
                if (l->propBuf[i] & (PE_IMAGE | PE_ANCHOR | PE_FORM)) {
 
526
                    if (active)
 
527
                        l->propBuf[i] |= PE_ACTIVE;
 
528
                    else
 
529
                        l->propBuf[i] &= ~PE_ACTIVE;
 
530
                }
 
531
            }
 
532
            if (active)
 
533
                redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY,
 
534
                                 an->start.pos, an->end.pos);
 
535
        }
 
536
        else if (prevhseq >= 0 && an->hseq == prevhseq) {
 
537
            if (active)
 
538
                redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY,
 
539
                                 an->start.pos, an->end.pos);
 
540
        }
 
541
    }
 
542
}
 
543
 
 
544
static void
 
545
drawAnchorCursor(Buffer *buf)
 
546
{
 
547
    Anchor *an;
 
548
    int hseq, prevhseq;
 
549
    int tline, eline;
 
550
 
 
551
    if (!buf->firstLine || !buf->hmarklist)
 
552
        return;
 
553
    if (!buf->href && !buf->formitem)
 
554
        return;
 
555
 
 
556
    an = retrieveCurrentAnchor(buf);
 
557
    if (!an)
 
558
        an = retrieveCurrentMap(buf);
 
559
    if (an)
 
560
        hseq = an->hseq;
 
561
    else
 
562
        hseq = -1;
 
563
    tline = buf->topLine->linenumber;
 
564
    eline = tline + buf->LINES;
 
565
    prevhseq = buf->hmarklist->prevhseq;
 
566
 
 
567
    if (buf->href) {
 
568
        drawAnchorCursor0(buf, buf->href, hseq, prevhseq, tline, eline, 1);
 
569
        drawAnchorCursor0(buf, buf->href, hseq, -1, tline, eline, 0);
 
570
    }
 
571
    if (buf->formitem) {
 
572
        drawAnchorCursor0(buf, buf->formitem, hseq, prevhseq, tline, eline, 1);
 
573
        drawAnchorCursor0(buf, buf->formitem, hseq, -1, tline, eline, 0);
 
574
    }
 
575
    buf->hmarklist->prevhseq = hseq;
 
576
}
 
577
 
 
578
static void
 
579
redrawNLine(Buffer *buf, int n)
 
580
{
 
581
    Line *l;
 
582
    int i;
 
583
 
 
584
#ifdef USE_COLOR
 
585
    if (useColor) {
 
586
        EFFECT_ANCHOR_END_C;
 
587
#ifdef USE_BG_COLOR
 
588
        setbcolor(bg_color);
 
589
#endif                          /* USE_BG_COLOR */
 
590
    }
 
591
#endif                          /* USE_COLOR */
 
592
    if (nTab > 1
 
593
#ifdef USE_MOUSE
 
594
        || mouse_action.menu_str
 
595
#endif
 
596
        ) {
 
597
        TabBuffer *t;
 
598
        int l;
 
599
 
 
600
        move(0, 0);
 
601
#ifdef USE_MOUSE
 
602
        if (mouse_action.menu_str)
 
603
            addstr(mouse_action.menu_str);
 
604
#endif
 
605
        clrtoeolx();
 
606
        for (t = FirstTab; t; t = t->nextTab) {
 
607
            move(t->y, t->x1);
 
608
            if (t == CurrentTab)
 
609
                bold();
 
610
            addch('[');
 
611
            l = t->x2 - t->x1 - 1 - get_strwidth(t->currentBuffer->buffername);
 
612
            if (l < 0)
 
613
                l = 0;
 
614
            if (l / 2 > 0)
 
615
                addnstr_sup(" ", l / 2);
 
616
            if (t == CurrentTab)
 
617
                EFFECT_ACTIVE_START;
 
618
            addnstr(t->currentBuffer->buffername, t->x2 - t->x1 - l);
 
619
            if (t == CurrentTab)
 
620
                EFFECT_ACTIVE_END;
 
621
            if ((l + 1) / 2 > 0)
 
622
                addnstr_sup(" ", (l + 1) / 2);
 
623
            move(t->y, t->x2);
 
624
            addch(']');
 
625
            if (t == CurrentTab)
 
626
                boldend();
 
627
        }
 
628
#if 0
 
629
        move(0, COLS - 2);
 
630
        addstr(" x");
 
631
#endif
 
632
        move(LastTab->y + 1, 0);
 
633
        for (i = 0; i < COLS; i++)
 
634
            addch('~');
 
635
    }
 
636
    for (i = 0, l = buf->topLine; i < buf->LINES; i++, l = l->next) {
 
637
        if (i >= buf->LINES - n || i < -n)
 
638
            l = redrawLine(buf, l, i + buf->rootY);
 
639
        if (l == NULL)
 
640
            break;
 
641
    }
 
642
    if (n > 0) {
 
643
        move(i + buf->rootY, 0);
 
644
        clrtobotx();
 
645
    }
 
646
 
 
647
#ifdef USE_IMAGE
 
648
    if (!(activeImage && displayImage && buf->img))
 
649
        return;
 
650
    move(buf->cursorY + buf->rootY, buf->cursorX + buf->rootX);
 
651
    for (i = 0, l = buf->topLine; i < buf->LINES && l; i++, l = l->next) {
 
652
        if (i >= buf->LINES - n || i < -n)
 
653
            redrawLineImage(buf, l, i + buf->rootY);
 
654
    }
 
655
    getAllImage(buf);
 
656
#endif
 
657
}
 
658
 
 
659
static Line *
 
660
redrawLine(Buffer *buf, Line *l, int i)
 
661
{
 
662
    int j, pos, rcol, ncol, delta = 1;
 
663
    int column = buf->currentColumn;
 
664
    char *p;
 
665
    Lineprop *pr;
 
666
#ifdef USE_ANSI_COLOR
 
667
    Linecolor *pc;
 
668
#endif
 
669
#ifdef USE_COLOR
 
670
    Anchor *a;
 
671
    ParsedURL url;
 
672
    int k, vpos = -1;
 
673
#endif
 
674
 
 
675
    if (l == NULL) {
 
676
        if (buf->pagerSource) {
 
677
            l = getNextPage(buf, buf->LINES + buf->rootY - i);
 
678
            if (l == NULL)
 
679
                return NULL;
 
680
        }
 
681
        else
 
682
            return NULL;
 
683
    }
 
684
    move(i, 0);
 
685
    if (showLineNum) {
 
686
        char tmp[16];
 
687
        if (!buf->rootX) {
 
688
            if (buf->lastLine->real_linenumber > 0)
 
689
                buf->rootX = (int)(log(buf->lastLine->real_linenumber + 0.1)
 
690
                                   / log(10)) + 2;
 
691
            if (buf->rootX < 5)
 
692
                buf->rootX = 5;
 
693
            if (buf->rootX > COLS)
 
694
                buf->rootX = COLS;
 
695
            buf->COLS = COLS - buf->rootX;
 
696
        }
 
697
        if (l->real_linenumber && !l->bpos)
 
698
            sprintf(tmp, "%*ld:", buf->rootX - 1, l->real_linenumber);
 
699
        else
 
700
            sprintf(tmp, "%*s ", buf->rootX - 1, "");
 
701
        addstr(tmp);
 
702
    }
 
703
    move(i, buf->rootX);
 
704
    if (l->width < 0)
 
705
        l->width = COLPOS(l, l->len);
 
706
    if (l->len == 0 || l->width - 1 < column) {
 
707
        clrtoeolx();
 
708
        return l;
 
709
    }
 
710
    /* need_clrtoeol(); */
 
711
    pos = columnPos(l, column);
 
712
    p = &(l->lineBuf[pos]);
 
713
    pr = &(l->propBuf[pos]);
 
714
#ifdef USE_ANSI_COLOR
 
715
    if (useColor && l->colorBuf)
 
716
        pc = &(l->colorBuf[pos]);
 
717
    else
 
718
        pc = NULL;
 
719
#endif
 
720
    rcol = COLPOS(l, pos);
 
721
 
 
722
    for (j = 0; rcol - column < buf->COLS && pos + j < l->len; j += delta) {
 
723
#ifdef USE_COLOR
 
724
        if (useVisitedColor && vpos <= pos + j && !(pr[j] & PE_VISITED)) {
 
725
            a = retrieveAnchor(buf->href, l->linenumber, pos + j);
 
726
            if (a) {
 
727
                parseURL2(a->url, &url, baseURL(buf));
 
728
                if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
 
729
                    for (k = a->start.pos; k < a->end.pos; k++)
 
730
                        pr[k - pos] |= PE_VISITED;
 
731
                }
 
732
                vpos = a->end.pos;
 
733
            }
 
734
        }
 
735
#endif
 
736
#ifdef USE_M17N
 
737
        delta = wtf_len((wc_uchar *) & p[j]);
 
738
#endif
 
739
        ncol = COLPOS(l, pos + j + delta);
 
740
        if (ncol - column > buf->COLS)
 
741
            break;
 
742
#ifdef USE_ANSI_COLOR
 
743
        if (pc)
 
744
            do_color(pc[j]);
 
745
#endif
 
746
        if (rcol < column) {
 
747
            for (rcol = column; rcol < ncol; rcol++)
 
748
                addChar(' ', 0);
 
749
            continue;
 
750
        }
 
751
        if (p[j] == '\t') {
 
752
            for (; rcol < ncol; rcol++)
 
753
                addChar(' ', 0);
 
754
        }
 
755
        else {
 
756
#ifdef USE_M17N
 
757
            addMChar(&p[j], pr[j], delta);
 
758
#else
 
759
            addChar(p[j], pr[j]);
 
760
#endif
 
761
        }
 
762
        rcol = ncol;
 
763
    }
 
764
    if (somode) {
 
765
        somode = FALSE;
 
766
        standend();
 
767
    }
 
768
    if (ulmode) {
 
769
        ulmode = FALSE;
 
770
        underlineend();
 
771
    }
 
772
    if (bomode) {
 
773
        bomode = FALSE;
 
774
        boldend();
 
775
    }
 
776
    if (emph_mode) {
 
777
        emph_mode = FALSE;
 
778
        boldend();
 
779
    }
 
780
 
 
781
    if (anch_mode) {
 
782
        anch_mode = FALSE;
 
783
        EFFECT_ANCHOR_END;
 
784
    }
 
785
    if (imag_mode) {
 
786
        imag_mode = FALSE;
 
787
        EFFECT_IMAGE_END;
 
788
    }
 
789
    if (form_mode) {
 
790
        form_mode = FALSE;
 
791
        EFFECT_FORM_END;
 
792
    }
 
793
    if (visited_mode) {
 
794
        visited_mode = FALSE;
 
795
        EFFECT_VISITED_END;
 
796
    }
 
797
    if (active_mode) {
 
798
        active_mode = FALSE;
 
799
        EFFECT_ACTIVE_END;
 
800
    }
 
801
    if (mark_mode) {
 
802
        mark_mode = FALSE;
 
803
        EFFECT_MARK_END;
 
804
    }
 
805
    if (graph_mode) {
 
806
        graph_mode = FALSE;
 
807
        graphend();
 
808
    }
 
809
#ifdef USE_ANSI_COLOR
 
810
    if (color_mode)
 
811
        do_color(0);
 
812
#endif
 
813
    if (rcol - column < buf->COLS)
 
814
        clrtoeolx();
 
815
    return l;
 
816
}
 
817
 
 
818
#ifdef USE_IMAGE
 
819
static Line *
 
820
redrawLineImage(Buffer *buf, Line *l, int i)
 
821
{
 
822
    int j, pos, rcol;
 
823
    int column = buf->currentColumn;
 
824
    Anchor *a;
 
825
    int x, y, sx, sy, w, h;
 
826
 
 
827
    if (l == NULL)
 
828
        return NULL;
 
829
    if (l->width < 0)
 
830
        l->width = COLPOS(l, l->len);
 
831
    if (l->len == 0 || l->width - 1 < column)
 
832
        return l;
 
833
    pos = columnPos(l, column);
 
834
    rcol = COLPOS(l, pos);
 
835
    for (j = 0; rcol - column < buf->COLS && pos + j < l->len; j++) {
 
836
        if (rcol - column < 0) {
 
837
            rcol = COLPOS(l, pos + j + 1);
 
838
            continue;
 
839
        }
 
840
        a = retrieveAnchor(buf->img, l->linenumber, pos + j);
 
841
        if (a && a->image && a->image->touch < image_touch) {
 
842
            Image *image = a->image;
 
843
            ImageCache *cache;
 
844
 
 
845
            cache = image->cache = getImage(image, baseURL(buf),
 
846
                                            buf->image_flag);
 
847
            if (cache) {
 
848
                if ((image->width < 0 && cache->width > 0) ||
 
849
                    (image->height < 0 && cache->height > 0)) {
 
850
                    image->width = cache->width;
 
851
                    image->height = cache->height;
 
852
                    buf->need_reshape = TRUE;
 
853
                }
 
854
                x = (int)((rcol - column + buf->rootX) * pixel_per_char);
 
855
                y = (int)(i * pixel_per_line);
 
856
                sx = (int)((rcol - COLPOS(l, a->start.pos)) * pixel_per_char);
 
857
                sy = (int)((l->linenumber - image->y) * pixel_per_line);
 
858
                if (sx == 0 && x + image->xoffset >= 0)
 
859
                    x += image->xoffset;
 
860
                else
 
861
                    sx -= image->xoffset;
 
862
                if (sy == 0 && y + image->yoffset >= 0)
 
863
                    y += image->yoffset;
 
864
                else
 
865
                    sy -= image->yoffset;
 
866
                if (image->width > 0)
 
867
                    w = image->width - sx;
 
868
                else
 
869
                    w = (int)(8 * pixel_per_char - sx);
 
870
                if (image->height > 0)
 
871
                    h = image->height - sy;
 
872
                else
 
873
                    h = (int)(pixel_per_line - sy);
 
874
                if (w > (int)((buf->rootX + buf->COLS) * pixel_per_char - x))
 
875
                    w = (int)((buf->rootX + buf->COLS) * pixel_per_char - x);
 
876
                if (h > (int)(LASTLINE * pixel_per_line - y))
 
877
                    h = (int)(LASTLINE * pixel_per_line - y);
 
878
                addImage(cache, x, y, sx, sy, w, h);
 
879
                image->touch = image_touch;
 
880
                draw_image_flag = TRUE;
 
881
            }
 
882
        }
 
883
        rcol = COLPOS(l, pos + j + 1);
 
884
    }
 
885
    return l;
 
886
}
 
887
#endif
 
888
 
 
889
static int
 
890
redrawLineRegion(Buffer *buf, Line *l, int i, int bpos, int epos)
 
891
{
 
892
    int j, pos, rcol, ncol, delta = 1;
 
893
    int column = buf->currentColumn;
 
894
    char *p;
 
895
    Lineprop *pr;
 
896
#ifdef USE_ANSI_COLOR
 
897
    Linecolor *pc;
 
898
#endif
 
899
    int bcol, ecol;
 
900
#ifdef USE_COLOR
 
901
    Anchor *a;
 
902
    ParsedURL url;
 
903
    int k, vpos = -1;
 
904
#endif
 
905
 
 
906
    if (l == NULL)
 
907
        return 0;
 
908
    pos = columnPos(l, column);
 
909
    p = &(l->lineBuf[pos]);
 
910
    pr = &(l->propBuf[pos]);
 
911
#ifdef USE_ANSI_COLOR
 
912
    if (useColor && l->colorBuf)
 
913
        pc = &(l->colorBuf[pos]);
 
914
    else
 
915
        pc = NULL;
 
916
#endif
 
917
    rcol = COLPOS(l, pos);
 
918
    bcol = bpos - pos;
 
919
    ecol = epos - pos;
 
920
 
 
921
    for (j = 0; rcol - column < buf->COLS && pos + j < l->len; j += delta) {
 
922
#ifdef USE_COLOR
 
923
        if (useVisitedColor && vpos <= pos + j && !(pr[j] & PE_VISITED)) {
 
924
            a = retrieveAnchor(buf->href, l->linenumber, pos + j);
 
925
            if (a) {
 
926
                parseURL2(a->url, &url, baseURL(buf));
 
927
                if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
 
928
                    for (k = a->start.pos; k < a->end.pos; k++)
 
929
                        pr[k - pos] |= PE_VISITED;
 
930
                }
 
931
                vpos = a->end.pos;
 
932
            }
 
933
        }
 
934
#endif
 
935
#ifdef USE_M17N
 
936
        delta = wtf_len((wc_uchar *) & p[j]);
 
937
#endif
 
938
        ncol = COLPOS(l, pos + j + delta);
 
939
        if (ncol - column > buf->COLS)
 
940
            break;
 
941
#ifdef USE_ANSI_COLOR
 
942
        if (pc)
 
943
            do_color(pc[j]);
 
944
#endif
 
945
        if (j >= bcol && j < ecol) {
 
946
            if (rcol < column) {
 
947
                move(i, buf->rootX);
 
948
                for (rcol = column; rcol < ncol; rcol++)
 
949
                    addChar(' ', 0);
 
950
                continue;
 
951
            }
 
952
            move(i, rcol - column + buf->rootX);
 
953
            if (p[j] == '\t') {
 
954
                for (; rcol < ncol; rcol++)
 
955
                    addChar(' ', 0);
 
956
            }
 
957
            else
 
958
#ifdef USE_M17N
 
959
                addMChar(&p[j], pr[j], delta);
 
960
#else
 
961
                addChar(p[j], pr[j]);
 
962
#endif
 
963
        }
 
964
        rcol = ncol;
 
965
    }
 
966
    if (somode) {
 
967
        somode = FALSE;
 
968
        standend();
 
969
    }
 
970
    if (ulmode) {
 
971
        ulmode = FALSE;
 
972
        underlineend();
 
973
    }
 
974
    if (bomode) {
 
975
        bomode = FALSE;
 
976
        boldend();
 
977
    }
 
978
    if (emph_mode) {
 
979
        emph_mode = FALSE;
 
980
        boldend();
 
981
    }
 
982
 
 
983
    if (anch_mode) {
 
984
        anch_mode = FALSE;
 
985
        EFFECT_ANCHOR_END;
 
986
    }
 
987
    if (imag_mode) {
 
988
        imag_mode = FALSE;
 
989
        EFFECT_IMAGE_END;
 
990
    }
 
991
    if (form_mode) {
 
992
        form_mode = FALSE;
 
993
        EFFECT_FORM_END;
 
994
    }
 
995
    if (visited_mode) {
 
996
        visited_mode = FALSE;
 
997
        EFFECT_VISITED_END;
 
998
    }
 
999
    if (active_mode) {
 
1000
        active_mode = FALSE;
 
1001
        EFFECT_ACTIVE_END;
 
1002
    }
 
1003
    if (mark_mode) {
 
1004
        mark_mode = FALSE;
 
1005
        EFFECT_MARK_END;
 
1006
    }
 
1007
    if (graph_mode) {
 
1008
        graph_mode = FALSE;
 
1009
        graphend();
 
1010
    }
 
1011
#ifdef USE_ANSI_COLOR
 
1012
    if (color_mode)
 
1013
        do_color(0);
 
1014
#endif
 
1015
    return rcol - column;
 
1016
}
 
1017
 
 
1018
#define do_effect1(effect,modeflag,action_start,action_end) \
 
1019
if (m & effect) { \
 
1020
    if (!modeflag) { \
 
1021
        action_start; \
 
1022
        modeflag = TRUE; \
 
1023
    } \
 
1024
}
 
1025
 
 
1026
#define do_effect2(effect,modeflag,action_start,action_end) \
 
1027
if (modeflag) { \
 
1028
    action_end; \
 
1029
    modeflag = FALSE; \
 
1030
}
 
1031
 
 
1032
static void
 
1033
do_effects(Lineprop m)
 
1034
{
 
1035
    /* effect end */
 
1036
    do_effect2(PE_UNDER, ulmode, underline(), underlineend());
 
1037
    do_effect2(PE_STAND, somode, standout(), standend());
 
1038
    do_effect2(PE_BOLD, bomode, bold(), boldend());
 
1039
    do_effect2(PE_EMPH, emph_mode, bold(), boldend());
 
1040
    do_effect2(PE_ANCHOR, anch_mode, EFFECT_ANCHOR_START, EFFECT_ANCHOR_END);
 
1041
    do_effect2(PE_IMAGE, imag_mode, EFFECT_IMAGE_START, EFFECT_IMAGE_END);
 
1042
    do_effect2(PE_FORM, form_mode, EFFECT_FORM_START, EFFECT_FORM_END);
 
1043
    do_effect2(PE_VISITED, visited_mode, EFFECT_VISITED_START,
 
1044
               EFFECT_VISITED_END);
 
1045
    do_effect2(PE_ACTIVE, active_mode, EFFECT_ACTIVE_START, EFFECT_ACTIVE_END);
 
1046
    do_effect2(PE_MARK, mark_mode, EFFECT_MARK_START, EFFECT_MARK_END);
 
1047
    if (graph_mode) {
 
1048
        graphend();
 
1049
        graph_mode = FALSE;
 
1050
    }
 
1051
 
 
1052
    /* effect start */
 
1053
    do_effect1(PE_UNDER, ulmode, underline(), underlineend());
 
1054
    do_effect1(PE_STAND, somode, standout(), standend());
 
1055
    do_effect1(PE_BOLD, bomode, bold(), boldend());
 
1056
    do_effect1(PE_EMPH, emph_mode, bold(), boldend());
 
1057
    do_effect1(PE_ANCHOR, anch_mode, EFFECT_ANCHOR_START, EFFECT_ANCHOR_END);
 
1058
    do_effect1(PE_IMAGE, imag_mode, EFFECT_IMAGE_START, EFFECT_IMAGE_END);
 
1059
    do_effect1(PE_FORM, form_mode, EFFECT_FORM_START, EFFECT_FORM_END);
 
1060
    do_effect1(PE_VISITED, visited_mode, EFFECT_VISITED_START,
 
1061
               EFFECT_VISITED_END);
 
1062
    do_effect1(PE_ACTIVE, active_mode, EFFECT_ACTIVE_START, EFFECT_ACTIVE_END);
 
1063
    do_effect1(PE_MARK, mark_mode, EFFECT_MARK_START, EFFECT_MARK_END);
 
1064
}
 
1065
 
 
1066
#ifdef USE_ANSI_COLOR
 
1067
static void
 
1068
do_color(Linecolor c)
 
1069
{
 
1070
    if (c & 0x8)
 
1071
        setfcolor(c & 0x7);
 
1072
    else if (color_mode & 0x8)
 
1073
        setfcolor(basic_color);
 
1074
#ifdef USE_BG_COLOR
 
1075
    if (c & 0x80)
 
1076
        setbcolor((c >> 4) & 0x7);
 
1077
    else if (color_mode & 0x80)
 
1078
        setbcolor(bg_color);
 
1079
#endif
 
1080
    color_mode = c;
 
1081
}
 
1082
#endif
 
1083
 
 
1084
#ifdef USE_M17N
 
1085
void
 
1086
addChar(char c, Lineprop mode)
 
1087
{
 
1088
    addMChar(&c, mode, 1);
 
1089
}
 
1090
 
 
1091
void
 
1092
addMChar(char *p, Lineprop mode, size_t len)
 
1093
#else
 
1094
void
 
1095
addChar(char c, Lineprop mode)
 
1096
#endif
 
1097
{
 
1098
    Lineprop m = CharEffect(mode);
 
1099
#ifdef USE_M17N
 
1100
    char c = *p;
 
1101
 
 
1102
    if (mode & PC_WCHAR2)
 
1103
        return;
 
1104
#endif
 
1105
    do_effects(m);
 
1106
    if (mode & PC_SYMBOL) {
 
1107
        char **symbol;
 
1108
#ifdef USE_M17N
 
1109
        int w = (mode & PC_KANJI) ? 2 : 1;
 
1110
 
 
1111
        c = ((char)wtf_get_code((wc_uchar *) p) & 0x7f) - SYMBOL_BASE;
 
1112
#else
 
1113
        c -= SYMBOL_BASE;
 
1114
#endif
 
1115
        if (graph_ok() && c < N_GRAPH_SYMBOL) {
 
1116
            if (!graph_mode) {
 
1117
                graphstart();
 
1118
                graph_mode = TRUE;
 
1119
            }
 
1120
#ifdef USE_M17N
 
1121
            if (w == 2 && WcOption.use_wide)
 
1122
                addstr(graph2_symbol[(int)c]);
 
1123
            else
 
1124
#endif
 
1125
                addch(*graph_symbol[(int)c]);
 
1126
        }
 
1127
        else {
 
1128
#ifdef USE_M17N
 
1129
            symbol = get_symbol(DisplayCharset, &w);
 
1130
            addstr(symbol[(int)c]);
 
1131
#else
 
1132
            symbol = get_symbol();
 
1133
            addch(*symbol[(int)c]);
 
1134
#endif
 
1135
        }
 
1136
    }
 
1137
    else if (mode & PC_CTRL) {
 
1138
        switch (c) {
 
1139
        case '\t':
 
1140
            addch(c);
 
1141
            break;
 
1142
        case '\n':
 
1143
            addch(' ');
 
1144
            break;
 
1145
        case '\r':
 
1146
            break;
 
1147
        case DEL_CODE:
 
1148
            addstr("^?");
 
1149
            break;
 
1150
        default:
 
1151
            addch('^');
 
1152
            addch(c + '@');
 
1153
            break;
 
1154
        }
 
1155
    }
 
1156
#ifdef USE_M17N
 
1157
    else if (mode & PC_UNKNOWN) {
 
1158
        char buf[5];
 
1159
        sprintf(buf, "[%.2X]",
 
1160
                (unsigned char)wtf_get_code((wc_uchar *) p) | 0x80);
 
1161
        addstr(buf);
 
1162
    }
 
1163
    else
 
1164
        addmch(p, len);
 
1165
#else
 
1166
    else if (0x80 <= (unsigned char)c && (unsigned char)c <= NBSP_CODE)
 
1167
        addch(' ');
 
1168
    else
 
1169
        addch(c);
 
1170
#endif
 
1171
}
 
1172
 
 
1173
static GeneralList *message_list = NULL;
 
1174
 
 
1175
void
 
1176
record_err_message(char *s)
 
1177
{
 
1178
    if (fmInitialized) {
 
1179
        if (!message_list)
 
1180
            message_list = newGeneralList();
 
1181
        if (message_list->nitem >= LINES)
 
1182
            popValue(message_list);
 
1183
        pushValue(message_list, allocStr(s, -1));
 
1184
    }
 
1185
}
 
1186
 
 
1187
/* 
 
1188
 * List of error messages
 
1189
 */
 
1190
Buffer *
 
1191
message_list_panel(void)
 
1192
{
 
1193
    Str tmp = Strnew_size(LINES * COLS);
 
1194
    ListItem *p;
 
1195
 
 
1196
    /* FIXME: gettextize? */
 
1197
    Strcat_charp(tmp,
 
1198
                 "<html><head><title>List of error messages</title></head><body>"
 
1199
                 "<h1>List of error messages</h1><table cellpadding=0>\n");
 
1200
    if (message_list)
 
1201
        for (p = message_list->last; p; p = p->prev)
 
1202
            Strcat_m_charp(tmp, "<tr><td><pre>", html_quote(p->ptr),
 
1203
                           "</pre></td></tr>\n", NULL);
 
1204
    else
 
1205
        Strcat_charp(tmp, "<tr><td>(no message recorded)</td></tr>\n");
 
1206
    Strcat_charp(tmp, "</table></body></html>");
 
1207
    return loadHTMLString(tmp);
 
1208
}
 
1209
 
 
1210
void
 
1211
message(char *s, int return_x, int return_y)
 
1212
{
 
1213
    if (!fmInitialized)
 
1214
        return;
 
1215
    move(LASTLINE, 0);
 
1216
    addnstr(s, COLS - 1);
 
1217
    clrtoeolx();
 
1218
    move(return_y, return_x);
 
1219
}
 
1220
 
 
1221
void
 
1222
disp_err_message(char *s, int redraw_current)
 
1223
{
 
1224
    record_err_message(s);
 
1225
    disp_message(s, redraw_current);
 
1226
}
 
1227
 
 
1228
void
 
1229
disp_message_nsec(char *s, int redraw_current, int sec, int purge, int mouse)
 
1230
{
 
1231
    if (QuietMessage)
 
1232
        return;
 
1233
    if (!fmInitialized) {
 
1234
        fprintf(stderr, "%s\n", conv_to_system(s));
 
1235
        return;
 
1236
    }
 
1237
    if (CurrentTab != NULL && Currentbuf != NULL)
 
1238
        message(s, Currentbuf->cursorX + Currentbuf->rootX,
 
1239
                Currentbuf->cursorY + Currentbuf->rootY);
 
1240
    else
 
1241
        message(s, LASTLINE, 0);
 
1242
    refresh();
 
1243
#ifdef USE_MOUSE
 
1244
    if (mouse && use_mouse)
 
1245
        mouse_active();
 
1246
#endif
 
1247
    sleep_till_anykey(sec, purge);
 
1248
#ifdef USE_MOUSE
 
1249
    if (mouse && use_mouse)
 
1250
        mouse_inactive();
 
1251
#endif
 
1252
    if (CurrentTab != NULL && Currentbuf != NULL && redraw_current)
 
1253
        displayBuffer(Currentbuf, B_NORMAL);
 
1254
}
 
1255
 
 
1256
void
 
1257
disp_message(char *s, int redraw_current)
 
1258
{
 
1259
    disp_message_nsec(s, redraw_current, 10, FALSE, TRUE);
 
1260
}
 
1261
#ifdef USE_MOUSE
 
1262
void
 
1263
disp_message_nomouse(char *s, int redraw_current)
 
1264
{
 
1265
    disp_message_nsec(s, redraw_current, 10, FALSE, FALSE);
 
1266
}
 
1267
#endif
 
1268
 
 
1269
void
 
1270
set_delayed_message(char *s)
 
1271
{
 
1272
    delayed_msg = allocStr(s, -1);
 
1273
}
 
1274
 
 
1275
void
 
1276
cursorUp0(Buffer *buf, int n)
 
1277
{
 
1278
    if (buf->cursorY > 0)
 
1279
        cursorUpDown(buf, -1);
 
1280
    else {
 
1281
        buf->topLine = lineSkip(buf, buf->topLine, -n, FALSE);
 
1282
        if (buf->currentLine->prev != NULL)
 
1283
            buf->currentLine = buf->currentLine->prev;
 
1284
        arrangeLine(buf);
 
1285
    }
 
1286
}
 
1287
 
 
1288
void
 
1289
cursorUp(Buffer *buf, int n)
 
1290
{
 
1291
    Line *l = buf->currentLine;
 
1292
    if (buf->firstLine == NULL)
 
1293
        return;
 
1294
    while (buf->currentLine->prev && buf->currentLine->bpos)
 
1295
        cursorUp0(buf, n);
 
1296
    if (buf->currentLine == buf->firstLine) {
 
1297
        gotoLine(buf, l->linenumber);
 
1298
        arrangeLine(buf);
 
1299
        return;
 
1300
    }
 
1301
    cursorUp0(buf, n);
 
1302
    while (buf->currentLine->prev && buf->currentLine->bpos &&
 
1303
           buf->currentLine->bwidth >= buf->currentColumn + buf->visualpos)
 
1304
        cursorUp0(buf, n);
 
1305
}
 
1306
 
 
1307
void
 
1308
cursorDown0(Buffer *buf, int n)
 
1309
{
 
1310
    if (buf->cursorY < buf->LINES - 1)
 
1311
        cursorUpDown(buf, 1);
 
1312
    else {
 
1313
        buf->topLine = lineSkip(buf, buf->topLine, n, FALSE);
 
1314
        if (buf->currentLine->next != NULL)
 
1315
            buf->currentLine = buf->currentLine->next;
 
1316
        arrangeLine(buf);
 
1317
    }
 
1318
}
 
1319
 
 
1320
void
 
1321
cursorDown(Buffer *buf, int n)
 
1322
{
 
1323
    Line *l = buf->currentLine;
 
1324
    if (buf->firstLine == NULL)
 
1325
        return;
 
1326
    while (buf->currentLine->next && buf->currentLine->next->bpos)
 
1327
        cursorDown0(buf, n);
 
1328
    if (buf->currentLine == buf->lastLine) {
 
1329
        gotoLine(buf, l->linenumber);
 
1330
        arrangeLine(buf);
 
1331
        return;
 
1332
    }
 
1333
    cursorDown0(buf, n);
 
1334
    while (buf->currentLine->next && buf->currentLine->next->bpos &&
 
1335
           buf->currentLine->bwidth + buf->currentLine->width <
 
1336
           buf->currentColumn + buf->visualpos)
 
1337
        cursorDown0(buf, n);
 
1338
}
 
1339
 
 
1340
void
 
1341
cursorUpDown(Buffer *buf, int n)
 
1342
{
 
1343
    Line *cl = buf->currentLine;
 
1344
 
 
1345
    if (buf->firstLine == NULL)
 
1346
        return;
 
1347
    if ((buf->currentLine = currentLineSkip(buf, cl, n, FALSE)) == cl)
 
1348
        return;
 
1349
    arrangeLine(buf);
 
1350
}
 
1351
 
 
1352
void
 
1353
cursorRight(Buffer *buf, int n)
 
1354
{
 
1355
    int i, delta = 1, cpos, vpos2;
 
1356
    Line *l = buf->currentLine;
 
1357
    Lineprop *p;
 
1358
 
 
1359
    if (buf->firstLine == NULL)
 
1360
        return;
 
1361
    if (buf->pos == l->len && !(l->next && l->next->bpos))
 
1362
        return;
 
1363
    i = buf->pos;
 
1364
    p = l->propBuf;
 
1365
#ifdef USE_M17N
 
1366
    while (i + delta < l->len && p[i + delta] & PC_WCHAR2)
 
1367
        delta++;
 
1368
#endif
 
1369
    if (i + delta < l->len) {
 
1370
        buf->pos = i + delta;
 
1371
    }
 
1372
    else if (l->len == 0) {
 
1373
        buf->pos = 0;
 
1374
    }
 
1375
    else if (l->next && l->next->bpos) {
 
1376
        cursorDown0(buf, 1);
 
1377
        buf->pos = 0;
 
1378
        arrangeCursor(buf);
 
1379
        return;
 
1380
    }
 
1381
    else {
 
1382
        buf->pos = l->len - 1;
 
1383
#ifdef USE_M17N
 
1384
        while (buf->pos && p[buf->pos] & PC_WCHAR2)
 
1385
            buf->pos--;
 
1386
#endif
 
1387
    }
 
1388
    cpos = COLPOS(l, buf->pos);
 
1389
    buf->visualpos = l->bwidth + cpos - buf->currentColumn;
 
1390
    delta = 1;
 
1391
#ifdef USE_M17N
 
1392
    while (buf->pos + delta < l->len && p[buf->pos + delta] & PC_WCHAR2)
 
1393
        delta++;
 
1394
#endif
 
1395
    vpos2 = COLPOS(l, buf->pos + delta) - buf->currentColumn - 1;
 
1396
    if (vpos2 >= buf->COLS && n) {
 
1397
        columnSkip(buf, n + (vpos2 - buf->COLS) - (vpos2 - buf->COLS) % n);
 
1398
        buf->visualpos = l->bwidth + cpos - buf->currentColumn;
 
1399
    }
 
1400
    buf->cursorX = buf->visualpos - l->bwidth;
 
1401
}
 
1402
 
 
1403
void
 
1404
cursorLeft(Buffer *buf, int n)
 
1405
{
 
1406
    int i, delta = 1, cpos;
 
1407
    Line *l = buf->currentLine;
 
1408
    Lineprop *p;
 
1409
 
 
1410
    if (buf->firstLine == NULL)
 
1411
        return;
 
1412
    i = buf->pos;
 
1413
    p = l->propBuf;
 
1414
#ifdef USE_M17N
 
1415
    while (i - delta > 0 && p[i - delta] & PC_WCHAR2)
 
1416
        delta++;
 
1417
#endif
 
1418
    if (i >= delta)
 
1419
        buf->pos = i - delta;
 
1420
    else if (l->prev && l->bpos) {
 
1421
        cursorUp0(buf, -1);
 
1422
        buf->pos = buf->currentLine->len - 1;
 
1423
        arrangeCursor(buf);
 
1424
        return;
 
1425
    }
 
1426
    else
 
1427
        buf->pos = 0;
 
1428
    cpos = COLPOS(l, buf->pos);
 
1429
    buf->visualpos = l->bwidth + cpos - buf->currentColumn;
 
1430
    if (buf->visualpos - l->bwidth < 0 && n) {
 
1431
        columnSkip(buf,
 
1432
                   -n + buf->visualpos - l->bwidth - (buf->visualpos -
 
1433
                                                      l->bwidth) % n);
 
1434
        buf->visualpos = l->bwidth + cpos - buf->currentColumn;
 
1435
    }
 
1436
    buf->cursorX = buf->visualpos - l->bwidth;
 
1437
}
 
1438
 
 
1439
void
 
1440
cursorHome(Buffer *buf)
 
1441
{
 
1442
    buf->visualpos = 0;
 
1443
    buf->cursorX = buf->cursorY = 0;
 
1444
}
 
1445
 
 
1446
 
 
1447
/* 
 
1448
 * Arrange line,column and cursor position according to current line and
 
1449
 * current position.
 
1450
 */
 
1451
void
 
1452
arrangeCursor(Buffer *buf)
 
1453
{
 
1454
    int col, col2, pos;
 
1455
    int delta = 1;
 
1456
    if (buf == NULL || buf->currentLine == NULL)
 
1457
        return;
 
1458
    /* Arrange line */
 
1459
    if (buf->currentLine->linenumber - buf->topLine->linenumber >= buf->LINES
 
1460
        || buf->currentLine->linenumber < buf->topLine->linenumber) {
 
1461
        /*
 
1462
         * buf->topLine = buf->currentLine;
 
1463
         */
 
1464
        buf->topLine = lineSkip(buf, buf->currentLine, 0, FALSE);
 
1465
    }
 
1466
    /* Arrange column */
 
1467
    while (buf->pos < 0 && buf->currentLine->prev && buf->currentLine->bpos) {
 
1468
        pos = buf->pos + buf->currentLine->prev->len;
 
1469
        cursorUp0(buf, 1);
 
1470
        buf->pos = pos;
 
1471
    }
 
1472
    while (buf->pos >= buf->currentLine->len && buf->currentLine->next &&
 
1473
           buf->currentLine->next->bpos) {
 
1474
        pos = buf->pos - buf->currentLine->len;
 
1475
        cursorDown0(buf, 1);
 
1476
        buf->pos = pos;
 
1477
    }
 
1478
    if (buf->currentLine->len == 0 || buf->pos < 0)
 
1479
        buf->pos = 0;
 
1480
    else if (buf->pos >= buf->currentLine->len)
 
1481
        buf->pos = buf->currentLine->len - 1;
 
1482
#ifdef USE_M17N
 
1483
    while (buf->pos > 0 && buf->currentLine->propBuf[buf->pos] & PC_WCHAR2)
 
1484
        buf->pos--;
 
1485
#endif
 
1486
    col = COLPOS(buf->currentLine, buf->pos);
 
1487
#ifdef USE_M17N
 
1488
    while (buf->pos + delta < buf->currentLine->len &&
 
1489
           buf->currentLine->propBuf[buf->pos + delta] & PC_WCHAR2)
 
1490
        delta++;
 
1491
#endif
 
1492
    col2 = COLPOS(buf->currentLine, buf->pos + delta);
 
1493
    if (col < buf->currentColumn || col2 > buf->COLS + buf->currentColumn) {
 
1494
        buf->currentColumn = 0;
 
1495
        if (col2 > buf->COLS)
 
1496
            columnSkip(buf, col);
 
1497
    }
 
1498
    /* Arrange cursor */
 
1499
    buf->cursorY = buf->currentLine->linenumber - buf->topLine->linenumber;
 
1500
    buf->visualpos = buf->currentLine->bwidth +
 
1501
        COLPOS(buf->currentLine, buf->pos) - buf->currentColumn;
 
1502
    buf->cursorX = buf->visualpos - buf->currentLine->bwidth;
 
1503
#ifdef DISPLAY_DEBUG
 
1504
    fprintf(stderr,
 
1505
            "arrangeCursor: column=%d, cursorX=%d, visualpos=%d, pos=%d, len=%d\n",
 
1506
            buf->currentColumn, buf->cursorX, buf->visualpos, buf->pos,
 
1507
            buf->currentLine->len);
 
1508
#endif
 
1509
}
 
1510
 
 
1511
void
 
1512
arrangeLine(Buffer *buf)
 
1513
{
 
1514
    int i, cpos;
 
1515
 
 
1516
    if (buf->firstLine == NULL)
 
1517
        return;
 
1518
    buf->cursorY = buf->currentLine->linenumber - buf->topLine->linenumber;
 
1519
    i = columnPos(buf->currentLine, buf->currentColumn + buf->visualpos
 
1520
                  - buf->currentLine->bwidth);
 
1521
    cpos = COLPOS(buf->currentLine, i) - buf->currentColumn;
 
1522
    if (cpos >= 0) {
 
1523
        buf->cursorX = cpos;
 
1524
        buf->pos = i;
 
1525
    }
 
1526
    else if (buf->currentLine->len > i) {
 
1527
        buf->cursorX = 0;
 
1528
        buf->pos = i + 1;
 
1529
    }
 
1530
    else {
 
1531
        buf->cursorX = 0;
 
1532
        buf->pos = 0;
 
1533
    }
 
1534
#ifdef DISPLAY_DEBUG
 
1535
    fprintf(stderr,
 
1536
            "arrangeLine: column=%d, cursorX=%d, visualpos=%d, pos=%d, len=%d\n",
 
1537
            buf->currentColumn, buf->cursorX, buf->visualpos, buf->pos,
 
1538
            buf->currentLine->len);
 
1539
#endif
 
1540
}
 
1541
 
 
1542
void
 
1543
cursorXY(Buffer *buf, int x, int y)
 
1544
{
 
1545
    int oldX;
 
1546
 
 
1547
    cursorUpDown(buf, y - buf->cursorY);
 
1548
 
 
1549
    if (buf->cursorX > x) {
 
1550
        while (buf->cursorX > x)
 
1551
            cursorLeft(buf, buf->COLS / 2);
 
1552
    }
 
1553
    else if (buf->cursorX < x) {
 
1554
        while (buf->cursorX < x) {
 
1555
            oldX = buf->cursorX;
 
1556
 
 
1557
            cursorRight(buf, buf->COLS / 2);
 
1558
 
 
1559
            if (oldX == buf->cursorX)
 
1560
                break;
 
1561
        }
 
1562
        if (buf->cursorX > x)
 
1563
            cursorLeft(buf, buf->COLS / 2);
 
1564
    }
 
1565
}
 
1566
 
 
1567
void
 
1568
restorePosition(Buffer *buf, Buffer *orig)
 
1569
{
 
1570
    buf->topLine = lineSkip(buf, buf->firstLine, TOP_LINENUMBER(orig) - 1,
 
1571
                            FALSE);
 
1572
    gotoLine(buf, CUR_LINENUMBER(orig));
 
1573
    buf->pos = orig->pos;
 
1574
    if (buf->currentLine && orig->currentLine)
 
1575
        buf->pos += orig->currentLine->bpos - buf->currentLine->bpos;
 
1576
    buf->currentColumn = orig->currentColumn;
 
1577
    arrangeCursor(buf);
 
1578
}
 
1579
 
 
1580
/* Local Variables:    */
 
1581
/* c-basic-offset: 4   */
 
1582
/* tab-width: 8        */
 
1583
/* End:                */