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.59 by chris_moore, Sat Apr 10 23:11:58 2004 UTC vs.
Revision 1.63 by chris_moore, Thu Apr 15 00:38:13 2004 UTC

66 int font_ascent; 66 int font_ascent;
67 FILE *fp; /* FILE struct associated with file */ 67 FILE *fp; /* FILE struct associated with file */
68 ino_t inode; /* inode of the file opened */ 68 ino_t inode; /* inode of the file opened */
69 off_t last_size; /* file size at the last check */ 69 off_t last_size; /* file size at the last check */
70 unsigned long color; /* color to be used for printing */ 70 unsigned long color; /* color to be used for printing */
71 const char *colorname; /* color name/string */
71 int partial; /* true if the last line isn't complete */ 72 int partial; /* true if the last line isn't complete */
72 int lastpartial; /* true if the previous output wasn't complete */ 73 int lastpartial; /* true if the previous output wasn't complete */
73 struct line_node *last; /* last line we output */ 74 struct line_node *last; /* last line we output */
74 int modified; /* true if line is modified & needs displaying */ 75 int modified; /* true if line is modified & needs displaying */
75}; 76};
122struct timeval interval = { 2, 400000 }; 123struct timeval interval = { 2, 400000 };
123 124
124/* command line options */ 125/* command line options */
125int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename, 126int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename,
126 opt_outline, opt_noflicker, opt_whole, opt_update, opt_wordwrap, 127 opt_outline, opt_noflicker, opt_whole, opt_update, opt_wordwrap,
127 opt_justify, geom_mask, reload = 0; 128 opt_justify, geom_mask, opt_minspace, reload;
128const char *command = NULL, 129const char *command = NULL,
129 *fontname = USE_FONT, *dispname = NULL, *def_color = DEF_COLOR, 130 *fontname = USE_FONT, *dispname = NULL, *def_color = DEF_COLOR,
130 *continuation = "|| ", *cont_color = DEF_CONT_COLOR; 131 *continuation = "|| ", *cont_color = DEF_CONT_COLOR;
131 132
132struct logfile_entry *loglist = NULL, *loglist_tail = NULL; 133struct logfile_entry *loglist = NULL, *loglist_tail = NULL;
151/* prototypes */ 152/* prototypes */
152void list_files (int); 153void list_files (int);
153void force_reopen (int); 154void force_reopen (int);
154void force_refresh (int); 155void force_refresh (int);
155void blank_window (int); 156void blank_window (int);
157#ifdef USE_TOON_GET_ROOT_WINDOW
158Window ToonGetRootWindow(Display *, int, Window *);
159#endif /* USE_TOON_GET_ROOT_WINDOW */
156 160
157void InitWindow (void); 161void InitWindow (void);
158unsigned long GetColor (const char *); 162unsigned long GetColor (const char *);
159void redraw (int); 163void redraw (int);
160void refresh (int, int, int, int); 164void refresh (int, int, int, int);
221 fprintf (stderr, "can't allocate %s\n", ColorName); 225 fprintf (stderr, "can't allocate %s\n", ColorName);
222 226
223 return Color.pixel; 227 return Color.pixel;
224} 228}
225 229
230#ifndef USE_TOON_GET_ROOT_WINDOW
226static Window 231static void
227root_window (Display * display, int screen_number) 232find_root_window (Display *display, int screen_number)
228{ 233{
234 if (!root)
235 {
229 Atom SWM_VROOT = XInternAtom (display, "__SWM_VROOT", False); 236 Atom SWM_VROOT = XInternAtom (display, "__SWM_VROOT", False);
237 Atom NAUTILUS_DESKTOP_WINDOW_ID = XInternAtom (display, "NAUTILUS_DESKTOP_WINDOW_ID", False);
230 Window real_root_window = RootWindow (display, screen_number); 238 root = RootWindow (display, screen_number);
231 239
232 if (root) /* root window set via option */
233 return root;
234
235 if (SWM_VROOT != None)
236 {
237 Window unused, *windows; 240 Window unused, *windows = 0;
238 unsigned int count; 241 unsigned int count;
239 242
243 Atom type;
244 int format;
245 unsigned long nitems, bytes_after_return;
246 unsigned char *virtual_root_window;
247
248 if (XGetWindowProperty (display, root, NAUTILUS_DESKTOP_WINDOW_ID,
249 0, 1, False, XA_WINDOW, &type, &format,
250 &nitems, &bytes_after_return,
251 &virtual_root_window) == Success
252 && type == XA_WINDOW)
253 {
254 if (XQueryTree (display, *(Window *)virtual_root_window, &unused, &unused, &windows, &count))
255 root = windows[count - 1];
256
257 XFree (virtual_root_window);
258 }
240 if (XQueryTree (display, real_root_window, &unused, &unused, &windows, &count)) 259 else if (XQueryTree (display, root, &unused, &unused, &windows, &count))
241 { 260 {
242 int i; 261 int i;
243 262
244 for (i = 0; i < count; i++) 263 for (i = 0; i < count; i++)
245 { 264 {
246 Atom type;
247 int format;
248 unsigned long nitems, bytes_after_return;
249 unsigned char *virtual_root_window;
250
251 if (XGetWindowProperty (display, windows[i], SWM_VROOT, 265 if (XGetWindowProperty (display, windows[i], SWM_VROOT,
252 0, 1, False, XA_WINDOW, &type, &format, 266 0, 1, False, XA_WINDOW, &type, &format,
253 &nitems, &bytes_after_return, 267 &nitems, &bytes_after_return,
254 &virtual_root_window) == Success) 268 &virtual_root_window) == Success
269 && type == XA_WINDOW)
255 { 270 {
256 if (type != None)
257 {
258 if (type == XA_WINDOW)
259 {
260 root = *(Window *)virtual_root_window; 271 root = *(Window *)virtual_root_window;
261 XFree (windows);
262 XFree (virtual_root_window); 272 XFree (virtual_root_window);
263 return root;
264 }
265 else
266 fprintf (stderr, "__SWM_VROOT property type mismatch");
267 } 273 break;
268 } 274 }
269 else 275 }
270 fprintf (stderr,
271 "failed to get __SWM_VROOT property on window 0x%lx",
272 windows[i]);
273 }
274 276
275 if (count)
276 XFree (windows); 277 XFree (windows);
277 } 278 }
278 else 279 else
279 fprintf (stderr, "Can't query tree on root window 0x%lx", 280 fprintf (stderr, "Can't query tree on root window 0x%lx", root);
280 real_root_window);
281 } 281 }
282 else
283 /* This shouldn't happen. The Xlib documentation is wrong BTW. */
284 fprintf (stderr, "Can't intern atom __SWM_VROOT");
285
286 return real_root_window;
287} 282}
283#endif /* USE_TOON_GET_ROOT_WINDOW */
288 284
289void 285void
290InitWindow (void) 286InitWindow (void)
291{ 287{
292 XGCValues gcv; 288 XGCValues gcv;
302 298
303 screen = DefaultScreen (disp); 299 screen = DefaultScreen (disp);
304 ScreenHeight = DisplayHeight (disp, screen); 300 ScreenHeight = DisplayHeight (disp, screen);
305 ScreenWidth = DisplayWidth (disp, screen); 301 ScreenWidth = DisplayWidth (disp, screen);
306 302
307 root = root_window (disp, screen); 303 find_root_window (disp, screen);
308 304
309 gcm = GCBackground; 305 gcm = GCBackground;
310 gcv.graphics_exposures = True; 306 gcv.graphics_exposures = True;
311 WinGC = XCreateGC (disp, root, gcm, &gcv); 307 WinGC = XCreateGC (disp, root, gcm, &gcv);
312 XMapWindow (disp, root); 308 XMapWindow (disp, root);
309
313 XSetForeground (disp, WinGC, GetColor (DEF_COLOR)); 310 XSetForeground (disp, WinGC, GetColor (DEF_COLOR));
314 311
315 for (e = loglist; e; e = e->next) 312 for (e = loglist; e; e = e->next)
316 { 313 {
317 char **missing_charset_list; 314 char **missing_charset_list;
340 XFontSetExtents *xfe = XExtentsOfFontSet (e->fontset); 337 XFontSetExtents *xfe = XExtentsOfFontSet (e->fontset);
341 338
342 e->font_height = xfe->max_logical_extent.height; 339 e->font_height = xfe->max_logical_extent.height;
343 e->font_ascent = -xfe->max_logical_extent.y; 340 e->font_ascent = -xfe->max_logical_extent.y;
344 } 341 }
342
343 if (e->font_height > height - effect_y_space)
344 {
345 fprintf(stderr, "\n the display isn't tall enough to display a single line in font '%s'\n",
346 e->fontname);
347 fprintf(stderr, "\n the geometry in use is %d pixels tall\n", height);
348 fprintf(stderr, "\n font '%s' is %d pixels tall\n", e->fontname, e->font_height);
349 if (effect_y_space)
350 fprintf(stderr, "\n the shade or outline options need an extra %d pixel%s of vertical space\n",
351 effect_y_space, effect_y_space == 1 ? "" : "s");
352 fprintf(stderr, "\n");
353 exit(1);
354 }
345 } 355 }
346 356
347 if (geom_mask & XNegative) 357 if (geom_mask & XNegative)
348 win_x = win_x + ScreenWidth - width; 358 win_x = win_x + ScreenWidth - width;
349 if (geom_mask & YNegative) 359 if (geom_mask & YNegative)
350 win_y = win_y + ScreenHeight - height; 360 win_y = win_y + ScreenHeight - height;
351 361
352 if (opt_outline)
353 { 362 {
354 /* adding outline increases the total width and height by 2 363 struct logfile_entry *e;
355 pixels each, and offsets the text one pixel right and one 364
356 pixel down */ 365 for (e = loglist; e; e = e->next)
357 effect_x_space = effect_y_space = 2; 366 e->color = GetColor (e->colorname);
358 effect_x_offset = effect_y_offset = 1;
359 } 367 }
360 else if (opt_shade)
361 {
362 /* adding a shadow increases the space used */
363 effect_x_space = abs (SHADE_X);
364 effect_y_space = abs (SHADE_Y);
365
366 /* if the shadow is to the right and below then we don't need
367 * to move the text to make space for it, but shadows to the left
368 * and above need accomodating */
369 effect_x_offset = SHADE_X > 0 ? 0 : -SHADE_X;
370 effect_y_offset = SHADE_Y > 0 ? 0 : -SHADE_Y;
371 }
372 else
373 {
374 effect_x_space = effect_y_space = 0;
375 effect_x_offset = effect_y_offset = 0;
376 }
377 368
378 XSelectInput (disp, root, ExposureMask | FocusChangeMask); 369 XSelectInput (disp, root, ExposureMask | FocusChangeMask);
379} 370}
380 371
381/* 372/*
569 XClearArea (disp, root, win_x, win_y + offset - (opt_reverse ? 0 : space), 560 XClearArea (disp, root, win_x, win_y + offset - (opt_reverse ? 0 : space),
570 width + MARGIN_OF_ERROR, space, False); 561 width + MARGIN_OF_ERROR, space, False);
571#endif 562#endif
572 } 563 }
573 564
565 /* at least one of the lines must fit in the allocated area. we've
566 * already checked at initialisation time that all the fonts are small
567 * enough to fit at least one line in the display area, but assert it
568 * again here to be sure */
569 assert(line != linelist);
570
574 /* any lines that didn't just get looked at are never going to be, so break the chain */ 571 /* any lines that didn't just get looked at are never going to be, so break the chain */
575 if (line) line->prev->next = 0; 572 if (line) line->prev->next = 0;
576 573
577 /* and throw them all away */ 574 /* and throw them all away */
578 while (line) 575 while (line)
1159 continue; 1156 continue;
1160 } 1157 }
1161 1158
1162 /* print filename if any, and if last line was from 1159 /* print filename if any, and if last line was from
1163 * different file */ 1160 * different file */
1164 if (!opt_nofilename && lastprinted != current && current->desc[0]) 1161 if (lastprinted != current)
1165 { 1162 {
1166 current->last = 0; 1163 current->last = 0;
1164 if (!opt_nofilename && current->desc[0])
1165 {
1167 insert_new_line (xstrdup ("["), current); 1166 insert_new_line (xstrdup ("["), current);
1168 append_to_existing_line (xstrdup (current->desc), current); 1167 append_to_existing_line (xstrdup (current->desc), current);
1169 append_to_existing_line (xstrdup ("]"), current); 1168 append_to_existing_line (xstrdup ("]"), current);
1170 } 1169 }
1170 }
1171 1171
1172 /* if we're dealing with partial lines, and the last 1172 /* if we're dealing with partial lines, and the last
1173 * time we showed the line it wasn't finished ... */ 1173 * time we showed the line it wasn't finished ... */
1174 if (!opt_whole && current->lastpartial) 1174 if (!opt_whole && current->lastpartial)
1175 { 1175 {
1283 char *transform = NULL; 1283 char *transform = NULL;
1284#endif 1284#endif
1285 1285
1286 setlocale (LC_CTYPE, ""); /* try to initialize the locale. */ 1286 setlocale (LC_CTYPE, ""); /* try to initialize the locale. */
1287 1287
1288 /* window needs to be initialized before colorlookups can be done */
1289 /* just a dummy to get the color lookups right */
1290 geom_mask = NoValue;
1291 InitWindow ();
1292
1293 for (i = 1; i < argc; i++) 1288 for (i = 1; i < argc; i++)
1294 { 1289 {
1295 const char *arg = argv[i]; 1290 const char *arg = argv[i];
1296 1291
1297 if (arg[0] == '-' && arg[1] != '\0' && arg[1] != ',') 1292 if (arg[0] == '-' && arg[1] != '\0' && arg[1] != ',')
1332 } 1327 }
1333 else if (!strcmp (arg, "-shade")) 1328 else if (!strcmp (arg, "-shade"))
1334 opt_shade = 1; 1329 opt_shade = 1;
1335 else if (!strcmp (arg, "-outline")) 1330 else if (!strcmp (arg, "-outline"))
1336 opt_outline = 1; 1331 opt_outline = 1;
1332 else if (!strcmp (arg, "-minspace"))
1333 opt_minspace = 1;
1337 else if (!strcmp (arg, "-noflicker")) 1334 else if (!strcmp (arg, "-noflicker"))
1338 opt_noflicker = 1; 1335 opt_noflicker = 1;
1339 else if (!strcmp (arg, "-frame")) 1336 else if (!strcmp (arg, "-frame"))
1340 opt_frame = 1; 1337 opt_frame = 1;
1341 else if (!strcmp (arg, "-no-filename")) 1338 else if (!strcmp (arg, "-no-filename"))
1425 perror (fname), exit (1); 1422 perror (fname), exit (1);
1426 1423
1427 e->desc = xstrdup (desc); 1424 e->desc = xstrdup (desc);
1428 } 1425 }
1429 1426
1430 e->color = GetColor (fcolor); 1427 e->colorname = fcolor;
1431 e->partial = 0; 1428 e->partial = 0;
1432 e->fontname = fontname; 1429 e->fontname = fontname;
1433 e->last = NULL; 1430 e->last = NULL;
1434 e->next = NULL; 1431 e->next = NULL;
1435 1432
1495 } 1492 }
1496 else 1493 else
1497 printf ("compiled '%s' OK to %x\n", transform, (int)transformre); 1494 printf ("compiled '%s' OK to %x\n", transform, (int)transformre);
1498 } 1495 }
1499#endif 1496#endif
1497
1498 if (opt_outline && !opt_minspace)
1499 {
1500 /* adding outline increases the total width and height by 2
1501 pixels each, and offsets the text one pixel right and one
1502 pixel down */
1503 effect_x_space = effect_y_space = 2;
1504 effect_x_offset = effect_y_offset = 1;
1505 }
1506 else if (opt_shade && !opt_minspace)
1507 {
1508 /* adding a shadow increases the space used */
1509 effect_x_space = abs (SHADE_X);
1510 effect_y_space = abs (SHADE_Y);
1511
1512 /* if the shadow is to the right and below then we don't need
1513 * to move the text to make space for it, but shadows to the left
1514 * and above need accomodating */
1515 effect_x_offset = SHADE_X > 0 ? 0 : -SHADE_X;
1516 effect_y_offset = SHADE_Y > 0 ? 0 : -SHADE_Y;
1517 }
1518 else
1519 {
1520 effect_x_space = effect_y_space = 0;
1521 effect_x_offset = effect_y_offset = 0;
1522 }
1500 1523
1501 InitWindow (); 1524 InitWindow ();
1502 1525
1503 install_signal (SIGINT, blank_window); 1526 install_signal (SIGINT, blank_window);
1504 install_signal (SIGQUIT, blank_window); 1527 install_signal (SIGQUIT, blank_window);
1587 " -update allow updates to old partial lines\n" 1610 " -update allow updates to old partial lines\n"
1588 " -cont string to prefix continued partial lines with\n" 1611 " -cont string to prefix continued partial lines with\n"
1589 " defaults to \"|| \"\n" 1612 " defaults to \"|| \"\n"
1590 " -wordwrap wrap long lines at spaces to avoid breaking words\n" 1613 " -wordwrap wrap long lines at spaces to avoid breaking words\n"
1591 " -shade add shading to font\n" 1614 " -shade add shading to font\n"
1615 " -outline add black outline to font\n"
1616 " -minspace force minimum line spacing\n"
1592 " -noinitial don't display the last file lines on\n" 1617 " -noinitial don't display the last file lines on\n"
1593 " startup\n" 1618 " startup\n"
1594 " -i | -interval seconds interval between checks (fractional\n" 1619 " -i | -interval seconds interval between checks (fractional\n"
1595 " values o.k.). Default 2.4 seconds\n" 1620 " values o.k.). Default 2.4 seconds\n"
1596 " -V display version information and exit\n" 1621 " -V display version information and exit\n"

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines