ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/root-tail/root-tail.c
(Generate patch)

Comparing root-tail/root-tail.c (file contents):
Revision 1.51 by chris_moore, Wed Apr 7 12:35:13 2004 UTC vs.
Revision 1.52 by chris_moore, Thu Apr 8 00:37:03 2004 UTC

1/* 1/*
2 * Copyright 2001 by Marco d'Itri <md@linux.it> 2 * Copyright 2001 by Marco d'Itri <md@linux.it>
3 * Copyright 2000,2001,2002,2003,2004 3 * Copyright 2000,2001,2002,2003,2004
4 * Marc Lehmann <pcg@goof.com>, 4 * Marc Lehmann <pcg@goof.com>,
5 * and many others, see README 5 * and many others, see README
6 * 6 *
7 * Original version by Mike Baker. 7 * Original version by Mike Baker.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
46#endif 46#endif
47 47
48#define SHADE_X 2 48#define SHADE_X 2
49#define SHADE_Y 2 49#define SHADE_Y 2
50 50
51/* some italic fonts still go over the margin - this margin of error cleans up the mess */
52#define MARGIN_OF_ERROR 2
53
51/* data structures */ 54/* data structures */
52struct logfile_entry 55struct logfile_entry
53{ 56{
54 struct logfile_entry *next; 57 struct logfile_entry *next;
55 58
56 char *fname; /* name of file */ 59 char *fname; /* name of file */
57 char *desc; /* alternative description */ 60 char *desc; /* alternative description */
58 char *buf; /* text read but not yet displayed */ 61 char *buf; /* text read but not yet displayed */
62 const char *fontname;
63 XFontSet fontset;
64 int font_height;
65 int font_ascent;
59 FILE *fp; /* FILE struct associated with file */ 66 FILE *fp; /* FILE struct associated with file */
60 ino_t inode; /* inode of the file opened */ 67 ino_t inode; /* inode of the file opened */
61 off_t last_size; /* file size at the last check */ 68 off_t last_size; /* file size at the last check */
62 unsigned long color; /* color to be used for printing */ 69 unsigned long color; /* color to be used for printing */
63 int partial; /* true if the last line isn't complete */ 70 int partial; /* true if the last line isn't complete */
90 97
91struct displaymatrix 98struct displaymatrix
92{ 99{
93 char *line; 100 char *line;
94 int len; 101 int len;
102 int offset;
95 int buffer_size; 103 int buffer_size;
96 unsigned long color; 104 unsigned long color;
97}; 105};
98 106
99/* global variables */ 107/* global variables */
100int debug = 1;
101
102struct line_node *linelist = NULL, *linelist_tail = NULL; 108struct line_node *linelist = NULL, *linelist_tail = NULL;
103struct displaymatrix *display; 109struct displaymatrix *display;
104int continuation_width = -1; 110int continuation_width = -1;
105int continuation_color; 111int continuation_color;
106int continuation_length; 112int continuation_length;
107 113
114/* HACK - ideally listlen will start at however many '~'s will fit on
115 * the screen */
108int width = STD_WIDTH, height = STD_HEIGHT, listlen; 116int width = STD_WIDTH, height = STD_HEIGHT, listlen = 50;
109int win_x = LOC_X, win_y = LOC_Y; 117int win_x = LOC_X, win_y = LOC_Y;
110int font_ascent, font_height;
111int effect_x_space, effect_y_space; /* how much space does shading / outlining take up */ 118int effect_x_space, effect_y_space; /* how much space does shading / outlining take up */
112int effect_x_offset, effect_y_offset; /* and how does it offset the usable space */ 119int effect_x_offset, effect_y_offset; /* and how does it offset the usable space */
113int do_reopen; 120int do_reopen;
114struct timeval interval = { 2, 400000 }; 121struct timeval interval = { 2, 400000 };
115XFontSet fontset;
116 122
117/* command line options */ 123/* command line options */
118int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename, 124int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename,
119 opt_outline, opt_noflicker, opt_whole, opt_update, opt_wordwrap, 125 opt_outline, opt_noflicker, opt_whole, opt_update, opt_wordwrap,
120 opt_justify, geom_mask, reload = 0; 126 opt_justify, geom_mask, reload = 0;
191} 197}
192 198
193void 199void
194blank_window (int dummy) 200blank_window (int dummy)
195{ 201{
196 XClearArea (disp, root, win_x - 2, win_y - 2, width + 5, height + 5, False); 202 XClearArea (disp, root, win_x, win_y, width + MARGIN_OF_ERROR, height, False);
197 XFlush (disp); 203 XFlush (disp);
198 exit (0); 204 exit (0);
199} 205}
200 206
201/* X related functions */ 207/* X related functions */
283InitWindow (void) 289InitWindow (void)
284{ 290{
285 XGCValues gcv; 291 XGCValues gcv;
286 unsigned long gcm; 292 unsigned long gcm;
287 int screen, ScreenWidth, ScreenHeight; 293 int screen, ScreenWidth, ScreenHeight;
294 struct logfile_entry *e;
288 295
289 if (!(disp = XOpenDisplay (dispname))) 296 if (!(disp = XOpenDisplay (dispname)))
290 { 297 {
291 fprintf (stderr, "Can't open display %s.\n", dispname); 298 fprintf (stderr, "Can't open display %s.\n", dispname);
292 exit (1); 299 exit (1);
302 gcv.graphics_exposures = True; 309 gcv.graphics_exposures = True;
303 WinGC = XCreateGC (disp, root, gcm, &gcv); 310 WinGC = XCreateGC (disp, root, gcm, &gcv);
304 XMapWindow (disp, root); 311 XMapWindow (disp, root);
305 XSetForeground (disp, WinGC, GetColor (DEF_COLOR)); 312 XSetForeground (disp, WinGC, GetColor (DEF_COLOR));
306 313
314 for (e = loglist; e; e = e->next)
307 { 315 {
308 char **missing_charset_list; 316 char **missing_charset_list;
309 int missing_charset_count; 317 int missing_charset_count;
310 char *def_string; 318 char *def_string;
311 319
312 fontset = XCreateFontSet (disp, fontname, 320 e->fontset = XCreateFontSet (disp, e->fontname,
313 &missing_charset_list, &missing_charset_count, 321 &missing_charset_list, &missing_charset_count,
314 &def_string); 322 &def_string);
315 323
316 if (missing_charset_count) 324 if (missing_charset_count)
325 {
326 fprintf (stderr,
327 "Missing charsets in String to FontSet conversion (%s)\n",
328 missing_charset_list[0]);
329 XFreeStringList (missing_charset_list);
330 }
331
332 if (!e->fontset)
333 {
334 fprintf (stderr, "unable to create fontset for font '%s', exiting.\n", e->fontname);
335 exit (1);
336 }
337
317 { 338 {
318 fprintf (stderr, 339 XFontSetExtents *xfe = XExtentsOfFontSet (e->fontset);
319 "Missing charsets in String to FontSet conversion (%s)\n", 340
320 missing_charset_list[0]); 341 e->font_height = xfe->max_logical_extent.height;
321 XFreeStringList (missing_charset_list); 342 e->font_ascent = -xfe->max_logical_extent.y;
322 } 343 }
323 }
324
325 if (!fontset)
326 { 344 }
327 fprintf (stderr, "unable to create fontset, exiting.\n");
328 exit (1);
329 }
330
331 {
332 XFontSetExtents *xfe = XExtentsOfFontSet (fontset);
333
334 font_height = xfe->max_logical_extent.height;
335 font_ascent = -xfe->max_logical_extent.y;
336 }
337 345
338 if (geom_mask & XNegative) 346 if (geom_mask & XNegative)
339 win_x = win_x + ScreenWidth - width; 347 win_x = win_x + ScreenWidth - width;
340 if (geom_mask & YNegative) 348 if (geom_mask & YNegative)
341 win_y = win_y + ScreenHeight - height; 349 win_y = win_y + ScreenHeight - height;
351 else if (opt_shade) 359 else if (opt_shade)
352 { 360 {
353 /* adding a shadow increases the space used */ 361 /* adding a shadow increases the space used */
354 effect_x_space = abs (SHADE_X); 362 effect_x_space = abs (SHADE_X);
355 effect_y_space = abs (SHADE_Y); 363 effect_y_space = abs (SHADE_Y);
364
356 /* if the shadow is to the right and below then we don't need 365 /* if the shadow is to the right and below then we don't need
357 * to move the text to make space for it, but shadows to the left 366 * to move the text to make space for it, but shadows to the left
358 * and above need accomodating */ 367 * and above need accomodating */
359 effect_x_offset = SHADE_X > 0 ? 0 : -SHADE_X; 368 effect_x_offset = SHADE_X > 0 ? 0 : -SHADE_X;
360 effect_y_offset = SHADE_Y > 0 ? 0 : -SHADE_Y; 369 effect_y_offset = SHADE_Y > 0 ? 0 : -SHADE_Y;
361 } 370 }
362 else 371 else
363 { 372 {
364 effect_x_space = effect_y_space = 0; 373 effect_x_space = effect_y_space = 0;
365 effect_x_offset = effect_y_offset = 0; 374 effect_x_offset = effect_y_offset = 0;
366 }
367
368 /* if we are using -shade or -outline, there will be less usable
369 * space for output */
370 listlen = (height - effect_y_space) / font_height;
371
372 if (!listlen)
373 {
374 fprintf (stderr, "height too small for a single line, setting to %d\n",
375 font_height);
376 listlen = 1;
377 } 375 }
378 376
379 XSelectInput (disp, root, ExposureMask | FocusChangeMask); 377 XSelectInput (disp, root, ExposureMask | FocusChangeMask);
380} 378}
381 379
392{ 390{
393 XSetClipMask (disp, WinGC, None); 391 XSetClipMask (disp, WinGC, None);
394 refresh (0, 32768, 1, redraw_all); 392 refresh (0, 32768, 1, redraw_all);
395} 393}
396 394
397void draw_text (Display *disp, Window root, XFontSet fontset, GC WinGC, int x, int y, struct line_node *line, int foreground) 395void draw_text (Display *disp, Window root, GC WinGC, int x, int y, struct line_node *line, int foreground)
398{ 396{
399 if (line->wrapped_right && opt_justify && line->breaks) 397 if (line->wrapped_right && opt_justify && line->breaks)
400 { 398 {
401 int i; 399 int i;
402 for (i = 0; i < line->num_words; i++) { 400 for (i = 0; i < line->num_words; i++) {
403 XmbDrawString (disp, root, fontset, WinGC, 401 XmbDrawString (disp, root, line->logfile->fontset, WinGC,
404 x + line->breaks[i].width + ((i * line->free_pixels) / (line->num_words - 1)) + continuation_width * line->wrapped_left, y, 402 x + line->breaks[i].width + ((i * line->free_pixels) / (line->num_words - 1)) + continuation_width * line->wrapped_left, y,
405 line->line + line->breaks[i].index, 403 line->line + line->breaks[i].index,
406 line->breaks[i].len); 404 line->breaks[i].len);
407 } 405 }
408 if (line->wrapped_left) 406 if (line->wrapped_left)
409 { 407 {
410 if (foreground) XSetForeground (disp, WinGC, continuation_color); 408 if (foreground) XSetForeground (disp, WinGC, continuation_color);
411 XmbDrawString (disp, root, fontset, WinGC, x, y, continuation, continuation_length); 409 XmbDrawString (disp, root, line->logfile->fontset, WinGC, x, y, continuation, continuation_length);
412 } 410 }
413 } 411 }
414 else 412 else
415 { 413 {
416 XmbDrawString (disp, root, fontset, WinGC, x + continuation_width * line->wrapped_left, y, line->line, line->len); 414 XmbDrawString (disp, root, line->logfile->fontset, WinGC, x + continuation_width * line->wrapped_left, y, line->line, line->len);
417 if (line->wrapped_left) 415 if (line->wrapped_left)
418 { 416 {
419 if (foreground) XSetForeground (disp, WinGC, continuation_color); 417 if (foreground) XSetForeground (disp, WinGC, continuation_color);
420 XmbDrawString (disp, root, fontset, WinGC, x, y, continuation, continuation_length); 418 XmbDrawString (disp, root, line->logfile->fontset, WinGC, x, y, continuation, continuation_length);
421 } 419 }
422 } 420 }
423} 421}
424 422
425/* Just redraw everything without clearing (i.e. after an EXPOSE event) */ 423/* Just redraw everything without clearing (i.e. after an EXPOSE event) */
426void 424void
427refresh (int miny, int maxy, int clear, int refresh_all) 425refresh (int miny, int maxy, int clear, int refresh_all)
428{ 426{
429 int lin = 0; 427 int lin = 0;
428 int space = height;
430 int offset; 429 int offset;
431 unsigned long black_color = GetColor ("black"); 430 unsigned long black_color = GetColor ("black");
432 struct line_node *line; 431 struct line_node *line;
433 int step_per_line; 432 int step_per_line;
434 int foreground = 0; 433 int foreground = 0;
435 434
436 if (opt_reverse) 435 if (opt_reverse)
437 {
438 step_per_line = font_height;
439 offset = font_ascent + effect_y_offset; 436 offset = effect_y_offset;
440 }
441 else 437 else
442 { 438 offset = height + effect_y_offset;
443 step_per_line = -font_height;
444 offset = (listlen - 1) * font_height + font_ascent + effect_y_offset;
445 }
446 439
447 miny -= win_y + font_height; 440 miny -= win_y;
448 maxy -= win_y - font_height; 441 maxy -= win_y;
449 442
450 if (clear && !opt_noflicker) 443 if (clear && !opt_noflicker)
451 XClearArea (disp, root, win_x, win_y, width, height, False); 444 XClearArea (disp, root, win_x, win_y, width + MARGIN_OF_ERROR, height, False);
452 445
453 for (line = linelist; line && lin < listlen; line = line->next, lin++, offset += step_per_line) 446 for (line = linelist; line; line = line->next, lin++)
454 { 447 {
455 struct displaymatrix *display_line = display + lin; 448 struct displaymatrix *display_line;
456 449
450 if (opt_noflicker && lin >= listlen)
451 {
452 int i = listlen;
453 listlen *= 1.5;
454 display = xrealloc(display, listlen * sizeof(struct displaymatrix));
455 for (; i < listlen; i++)
456 {
457 display[i].line = xstrdup ("");
458 display[i].len = 0;
459 display[i].offset = 0;
460 display[i].buffer_size = 0;
461 }
462 }
463
464 display_line = display + lin;
465
466 step_per_line = line->logfile->font_height + effect_y_space;
467 if (step_per_line > space)
468 break;
469
470 if (!opt_reverse)
471 offset -= step_per_line;
472
473 offset += line->logfile->font_ascent;
474
475 miny -= line->logfile->font_height;
476 maxy += line->logfile->font_height;
477
457 if (offset < miny || offset > maxy) 478 if (offset >= miny && offset <= maxy)
458 continue; 479 {
459
460 /* if this line is a different than it was, then it 480 /* if this line is a different than it was, then it
461 * needs displaying */ 481 * needs displaying */
462 if (!opt_noflicker 482 if (!opt_noflicker
463 || refresh_all 483 || refresh_all
464 || display_line->len != line->len 484 || display_line->len != line->len
465 || display_line->color != line->logfile->color 485 || display_line->color != line->logfile->color
486 || display_line->offset != offset
466 || memcmp (display_line->line, line->line, line->len)) 487 || memcmp (display_line->line, line->line, line->len))
467 { 488 {
468 /* don't bother updating the record of what has been 489 /* don't bother updating the record of what has been
469 * displayed if -noflicker isn't in effect, since we redraw 490 * displayed if -noflicker isn't in effect, since we redraw
470 * the whole display every time anyway */ 491 * the whole display every time anyway */
471 if (opt_noflicker) 492 if (opt_noflicker)
472 {
473 /* update the record of what has been displayed;
474 * first make sure the buffer is big enough */
475 if (display_line->buffer_size < line->len)
476 { 493 {
494 /* update the record of what has been displayed;
495 * first make sure the buffer is big enough */
496 if (display_line->buffer_size < line->len)
497 {
477 display_line->buffer_size = line->len; 498 display_line->buffer_size = line->len;
478 display_line->line = xrealloc (display_line->line, display_line->buffer_size); 499 display_line->line = xrealloc (display_line->line, display_line->buffer_size);
500 }
501
502 display_line->len = line->len;
503 display_line->color = line->logfile->color;
504 display_line->offset = offset;
505 memcpy (display_line->line, line->line, line->len);
506
507 if (clear)
508 {
509#ifdef DEBUG
510 static int toggle;
511 toggle = 1 - toggle;
512 XSetForeground (disp, WinGC, toggle ? GetColor ("cyan") : GetColor ("yellow"));
513 XFillRectangle (disp, root, WinGC, win_x, win_y + offset - line->logfile->font_ascent,
514 width, step_per_line);
515#else /* DEBUG */
516 XClearArea (disp, root, win_x, win_y + offset - line->logfile->font_ascent,
517 width + MARGIN_OF_ERROR, step_per_line, False);
518#endif /* DEBUG */
519 }
479 } 520 }
480 521
481 display_line->len = line->len;
482 display_line->color = line->logfile->color;
483 memcpy (display_line->line, line->line, line->len);
484
485 if (clear)
486 XClearArea (disp, root, win_x, win_y + offset - font_ascent,
487 width + effect_x_space, font_height + effect_y_space, False);
488 }
489
490 if (opt_outline) 522 if (opt_outline)
491 { 523 {
492 int x, y; 524 int x, y;
493 XSetForeground (disp, WinGC, black_color); 525 XSetForeground (disp, WinGC, black_color);
494 526
495 for (x = -1; x <= 1; x += 2) 527 for (x = -1; x <= 1; x += 2)
496 for (y = -1; y <= 1; y += 2) 528 for (y = -1; y <= 1; y += 2)
497 draw_text (disp, root, fontset, WinGC, 529 draw_text (disp, root, WinGC,
498 win_x + effect_x_offset + x, 530 win_x + effect_x_offset + x,
499 win_y + y + offset, line, foreground = 0); 531 win_y + y + offset, line, foreground = 0);
500 } 532 }
501 else if (opt_shade) 533 else if (opt_shade)
502 { 534 {
503 XSetForeground (disp, WinGC, black_color); 535 XSetForeground (disp, WinGC, black_color);
504 draw_text (disp, root, fontset, WinGC, 536 draw_text (disp, root, WinGC,
505 win_x + effect_x_offset + SHADE_X, 537 win_x + effect_x_offset + SHADE_X,
506 win_y + offset + SHADE_Y, line, foreground = 0); 538 win_y + offset + SHADE_Y, line, foreground = 0);
507 } 539 }
508 540
509 XSetForeground (disp, WinGC, line->logfile->color); 541 XSetForeground (disp, WinGC, line->logfile->color);
510 draw_text (disp, root, fontset, WinGC, 542 draw_text (disp, root, WinGC,
511 win_x + effect_x_offset, 543 win_x + effect_x_offset,
512 win_y + offset, line, foreground = 1); 544 win_y + offset, line, foreground = 1);
513 } 545 }
546 }
547
548 if (opt_reverse)
549 offset += step_per_line;
550 offset -= line->logfile->font_ascent;
551
552 miny += line->logfile->font_height;
553 maxy -= line->logfile->font_height;
554
555 space -= step_per_line;
556 }
557
558 if (space > 0 && clear)
559 {
560#ifdef DEBUG
561 XSetForeground (disp, WinGC, GetColor ("orange"));
562 XFillRectangle (disp, root, WinGC, win_x, win_y + offset - (opt_reverse ? 0 : space),
563 width, space);
564#else /* DEBUG */
565 XClearArea (disp, root, win_x, win_y + offset - (opt_reverse ? 0 : space),
566 width + MARGIN_OF_ERROR, space, False);
567#endif
514 } 568 }
515 569
516 /* any lines that didn't just get looked at are never going to be, so break the chain */ 570 /* any lines that didn't just get looked at are never going to be, so break the chain */
517 if (line) line->prev->next = 0; 571 if (line) line->prev->next = 0;
518 572
529 } 583 }
530 584
531 if (opt_frame) 585 if (opt_frame)
532 { 586 {
533 XSetForeground (disp, WinGC, GetColor (def_color)); 587 XSetForeground (disp, WinGC, GetColor (def_color));
588 /* note that XDrawRectangle() draws a rectangle one pixel bigger
589 * in both dimensions than you ask for, hence the subtractions.
590 * XFillRectangle() doesn't suffer from this problem */
534 XDrawRectangle (disp, root, WinGC, win_x - 0, win_y - 0, width - 1, height - 1); 591 XDrawRectangle (disp, root, WinGC, win_x - 0, win_y - 0, width - 1, height - 1);
535 } 592 }
536} 593}
537 594
538#if HAS_REGEX 595#if HAS_REGEX
565 622
566 printf ("regexp was matched by '%s' - replace with '%s'\n", s, transform_to); 623 printf ("regexp was matched by '%s' - replace with '%s'\n", s, transform_to);
567 printf ("match is from %d to %d\n", match_start, match_end); 624 printf ("match is from %d to %d\n", match_start, match_end);
568 if (new_len > old_len) 625 if (new_len > old_len)
569 s = xrealloc (s, old_whole_len + new_len - old_len); 626 s = xrealloc (s, old_whole_len + new_len - old_len);
570 627
571 if (new_len != old_len) 628 if (new_len != old_len)
572 { 629 {
573 memcpy (s + match_end + new_len - old_len, 630 memcpy (s + match_end + new_len - old_len,
574 s + match_end, 631 s + match_end,
575 old_whole_len - match_end); 632 old_whole_len - match_end);
666 logfile->lastpartial = logfile->partial; 723 logfile->lastpartial = logfile->partial;
667 /* there are 3 ways we could have exited the loop: reading '\n', 724 /* there are 3 ways we could have exited the loop: reading '\n',
668 * reaching EOF, or filling the buffer; the 2nd and 3rd of these 725 * reaching EOF, or filling the buffer; the 2nd and 3rd of these
669 * both result in a partial line */ 726 * both result in a partial line */
670 logfile->partial = ch != '\n'; 727 logfile->partial = ch != '\n';
671 728
672 if (logfile->partial && opt_whole) 729 if (logfile->partial && opt_whole)
673 return 0; 730 return 0;
674 731
675#if HAS_REGEX 732#if HAS_REGEX
676 transform_line (logfile->buf); 733 transform_line (logfile->buf);
704 else 761 else
705 file->inode = stats.st_ino; 762 file->inode = stats.st_ino;
706 763
707 if (opt_noinitial) 764 if (opt_noinitial)
708 fseek (file->fp, 0, SEEK_END); 765 fseek (file->fp, 0, SEEK_END);
709 else if (stats.st_size > (listlen + 1) * width) 766 else /* if (stats.st_size > (listlen + 1) * width)
710 /* HACK - 'width' is in pixels - how are we to know how much text will fit? */ 767 * HACK - 'width' is in pixels - how are we to know how much text will fit?
711 fseek (file->fp, -((listlen + 2) * width/10), SEEK_END); 768 * fseek (file->fp, -((listlen + 2) * width/10), SEEK_END); */
769 fseek (file->fp, -5000, SEEK_END);
712 770
713 file->last_size = stats.st_size; 771 file->last_size = stats.st_size;
714 return file->fp; 772 return file->fp;
715} 773}
716 774
841 899
842 /* only calculate the continuation's width once */ 900 /* only calculate the continuation's width once */
843 if (continuation_width == -1) 901 if (continuation_width == -1)
844 { 902 {
845 continuation_length = strlen (continuation); 903 continuation_length = strlen (continuation);
846 continuation_width = XmbTextEscapement (fontset, continuation, continuation_length); 904 continuation_width = XmbTextEscapement (log->fontset, continuation, continuation_length);
847 continuation_color = GetColor (cont_color); 905 continuation_color = GetColor (cont_color);
848 906
849 /* make an array to store information about the location of 907 /* make an array to store information about the location of
850 * spaces in the line */ 908 * spaces in the line */
851 if (opt_justify) 909 if (opt_justify)
876 len = mblen (p, l); 934 len = mblen (p, l);
877 if (len <= 0) 935 if (len <= 0)
878 len = 1; /* ignore (don't skip) illegal character sequences */ 936 len = 1; /* ignore (don't skip) illegal character sequences */
879 937
880 /* find the width in pixels of the next character */ 938 /* find the width in pixels of the next character */
881 cw = XmbTextEscapement (fontset, p, len); 939 cw = XmbTextEscapement (log->fontset, p, len);
882
883 if (opt_wordwrap && len == 1 && p[0] == ' ' && p != break_p + 1) 940 if (opt_wordwrap && len == 1 && p[0] == ' ' && p != break_p + 1)
884 { 941 {
885 break_p = p; 942 break_p = p;
886 width_at_break_p = w; 943 width_at_break_p = w;
887 spaces++; 944 spaces++;
928 /* if we're wrapping at spaces, and the line is long enough to 985 /* if we're wrapping at spaces, and the line is long enough to
929 * wrap, and we've seen a space already, and the space wasn't 986 * wrap, and we've seen a space already, and the space wasn't
930 * the first character on the line, then wrap at the space */ 987 * the first character on the line, then wrap at the space */
931 if (!wrapped) 988 if (!wrapped)
932 break; 989 break;
933 990
934 int prefix_len; 991 int prefix_len;
935 992
936 /* choose where to break the line */ 993 /* choose where to break the line */
937 if (opt_wordwrap && break_p && break_p != beg) 994 if (opt_wordwrap && break_p && break_p != beg)
938 { 995 {
954 breaks[spaces].len--; 1011 breaks[spaces].len--;
955 } 1012 }
956 } 1013 }
957 else 1014 else
958 prefix_len = p - beg; 1015 prefix_len = p - beg;
959 1016
960 /* make a copy of the tail end of the string */ 1017 /* make a copy of the tail end of the string */
961 p = xstrdup (p); 1018 p = xstrdup (p);
962 1019
963 /* and reduce the size of the head of the string */ 1020 /* and reduce the size of the head of the string */
964 log->last->line = xrealloc (log->last->line, prefix_len + 1); 1021 log->last->line = xrealloc (log->last->line, prefix_len + 1);
969 log->last->wrapped_right = 1; 1026 log->last->wrapped_right = 1;
970 1027
971 /* 'spaces' includes any space we broke on; we can only justify 1028 /* 'spaces' includes any space we broke on; we can only justify
972 * if there's at least one other space */ 1029 * if there's at least one other space */
973 if (opt_justify && spaces && 1030 if (opt_justify && spaces &&
974 width - effect_x_space - width_at_break_p < spaces * font_height) 1031 width - effect_x_space - width_at_break_p < spaces * log->font_height)
975 { 1032 {
976 int i; 1033 int i;
977 log->last->free_pixels = width - w; 1034 log->last->free_pixels = width - effect_x_space - w;
978 log->last->num_words = spaces + 1; 1035 log->last->num_words = spaces + 1;
979 log->last->breaks = malloc (log->last->num_words * sizeof (struct breakinfo)); 1036 log->last->breaks = malloc (log->last->num_words * sizeof (struct breakinfo));
980 for (i = 0; i < log->last->num_words; i++) 1037 for (i = 0; i < log->last->num_words; i++)
981 log->last->breaks[i] = breaks[i]; 1038 log->last->breaks[i] = breaks[i];
982 } 1039 }
983 1040
984 line = new_line_node (log); 1041 line = new_line_node (log);
985 line->line = p; 1042 line->line = p;
986 l = line->len = strlen (p); 1043 l = line->len = strlen (p);
987 1044
988 /* note that the tail end of the string is wrapped at its left */ 1045 /* note that the tail end of the string is wrapped at its left */
1020 1077
1021 new = concat_line (old, str); 1078 new = concat_line (old, str);
1022 free (str); 1079 free (str);
1023 log->last->line = new; 1080 log->last->line = new;
1024 log->last->len = strlen (new); 1081 log->last->len = strlen (new);
1025 possibly_split_long_line (log); 1082 possibly_split_long_line (log);
1026} 1083}
1027 1084
1028static void 1085static void
1029main_loop (void) 1086main_loop (void)
1030{ 1087{
1059 linelist_tail->next = e; 1116 linelist_tail->next = e;
1060 linelist_tail = e; 1117 linelist_tail = e;
1061 1118
1062 display[lin].line = xstrdup (""); 1119 display[lin].line = xstrdup ("");
1063 display[lin].len = 0; 1120 display[lin].len = 0;
1121 display[lin].offset = 0;
1064 display[lin].buffer_size = 0; 1122 display[lin].buffer_size = 0;
1065 } 1123 }
1066 1124
1067 for (;;) 1125 for (;;)
1068 { 1126 {
1082 * output was partial, and that partial line is not 1140 * output was partial, and that partial line is not
1083 * too close to the top of the screen, then update 1141 * too close to the top of the screen, then update
1084 * that partial line */ 1142 * that partial line */
1085 if (opt_update && current->lastpartial && current->last) 1143 if (opt_update && current->lastpartial && current->last)
1086 { 1144 {
1087 // int idx = current->index;
1088 append_to_existing_line (current->buf, current); 1145 append_to_existing_line (current->buf, current);
1089 // current->index = idx;
1090 current->buf = 0; 1146 current->buf = 0;
1091 continue; 1147 continue;
1092 } 1148 }
1093 1149
1094 /* if all we just read was a newline ending a line that we've already displayed, skip it */ 1150 /* if all we just read was a newline ending a line that we've already displayed, skip it */
1095 if (current->buf[0] == '\0' && current->lastpartial) 1151 if (current->buf[0] == '\0' && current->lastpartial)
1096 { 1152 {
1097 free(current->buf); 1153 free(current->buf);
1098 current->buf = 0; 1154 current->buf = 0;
1099 continue; 1155 continue;
1100 } 1156 }
1101 1157
1102 /* print filename if any, and if last line was from 1158 /* print filename if any, and if last line was from
1129 else 1185 else
1130 /* otherwise just make a plain and simple new line */ 1186 /* otherwise just make a plain and simple new line */
1131 insert_new_line (current->buf, current); 1187 insert_new_line (current->buf, current);
1132 1188
1133 current->buf = 0; 1189 current->buf = 0;
1134 // current->index = listlen - 1;
1135 lastprinted = current; 1190 lastprinted = current;
1136 } 1191 }
1137 } 1192 }
1138 1193
1139 if (need_update) 1194 if (need_update)
1336 } 1391 }
1337 1392
1338 e = xmalloc (sizeof (struct logfile_entry)); 1393 e = xmalloc (sizeof (struct logfile_entry));
1339 e->partial = 0; 1394 e->partial = 0;
1340 e->buf = 0; 1395 e->buf = 0;
1341 // e->index = -1;
1342 1396
1343 if (arg[0] == '-' && arg[1] == '\0') 1397 if (arg[0] == '-' && arg[1] == '\0')
1344 { 1398 {
1345 if ((e->fp = fdopen (0, "r")) == NULL) 1399 if ((e->fp = fdopen (0, "r")) == NULL)
1346 perror ("fdopen"), exit (1); 1400 perror ("fdopen"), exit (1);
1361 e->desc = xstrdup (desc); 1415 e->desc = xstrdup (desc);
1362 } 1416 }
1363 1417
1364 e->color = GetColor (fcolor); 1418 e->color = GetColor (fcolor);
1365 e->partial = 0; 1419 e->partial = 0;
1420 e->fontname = fontname;
1366 e->last = NULL; 1421 e->last = NULL;
1367 e->next = NULL; 1422 e->next = NULL;
1368 1423
1369 if (!loglist) 1424 if (!loglist)
1370 loglist = e; 1425 loglist = e;
1504} 1559}
1505 1560
1506void 1561void
1507display_help (char *myname) 1562display_help (char *myname)
1508{ 1563{
1509 printf ("Usage: %s [options] file1[,color[,desc]] " 1564 printf ("Usage: %s [options] file1[,color[,desc]]"
1510 "[file2[,color[,desc]] ...]\n", myname); 1565 "[options] [file2[,color[,desc]] ...]\n", myname);
1511 printf (" -g | -geometry geometry -g WIDTHxHEIGHT+X+Y\n" 1566 printf (" -g | -geometry geometry -g WIDTHxHEIGHT+X+Y\n"
1512 " -color color use color $color as default\n" 1567 " -color color use color $color as default\n"
1513 " -reload sec command reload after $sec and run command\n" 1568 " -reload sec command reload after $sec and run command\n"
1514 " -id id window id to use instead of the root window\n" 1569 " -id id window id to use instead of the root window\n"
1515 " -font FONTSPEC (-fn) font to use\n" 1570 " -font FONTSPEC (-fn) font to use\n"

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines