… | |
… | |
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 | }; |
… | |
… | |
122 | struct timeval interval = { 2, 400000 }; |
123 | struct timeval interval = { 2, 400000 }; |
123 | |
124 | |
124 | /* command line options */ |
125 | /* command line options */ |
125 | int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename, |
126 | int 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; |
128 | const char *command = NULL, |
129 | const 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 | |
132 | struct logfile_entry *loglist = NULL, *loglist_tail = NULL; |
133 | struct logfile_entry *loglist = NULL, *loglist_tail = NULL; |
133 | |
134 | |
134 | Display *disp; |
135 | Display *disp; |
135 | Window root; |
136 | Window root; |
136 | #ifdef USE_TOON_GET_ROOT_WINDOW |
|
|
137 | Window real_root; |
|
|
138 | #endif /* USE_TOON_GET_ROOT_WINDOW */ |
|
|
139 | GC WinGC; |
137 | GC WinGC; |
140 | |
138 | |
141 | #if HAS_REGEX |
139 | #if HAS_REGEX |
142 | struct re_list |
140 | struct re_list |
143 | { |
141 | { |
… | |
… | |
216 | GetColor (const char *ColorName) |
214 | GetColor (const char *ColorName) |
217 | { |
215 | { |
218 | XColor Color; |
216 | XColor Color; |
219 | XWindowAttributes Attributes; |
217 | XWindowAttributes Attributes; |
220 | |
218 | |
221 | #ifdef USE_TOON_GET_ROOT_WINDOW |
|
|
222 | XGetWindowAttributes (disp, real_root, &Attributes); |
|
|
223 | #else /* USE_TOON_GET_ROOT_WINDOW */ |
|
|
224 | XGetWindowAttributes (disp, root, &Attributes); |
219 | XGetWindowAttributes (disp, root, &Attributes); |
225 | #endif /* USE_TOON_GET_ROOT_WINDOW */ |
|
|
226 | Color.pixel = 0; |
220 | Color.pixel = 0; |
227 | |
221 | |
228 | if (!XParseColor (disp, Attributes.colormap, ColorName, &Color)) |
222 | if (!XParseColor (disp, Attributes.colormap, ColorName, &Color)) |
229 | fprintf (stderr, "can't parse %s\n", ColorName); |
223 | fprintf (stderr, "can't parse %s\n", ColorName); |
230 | else if (!XAllocColor (disp, Attributes.colormap, &Color)) |
224 | else if (!XAllocColor (disp, Attributes.colormap, &Color)) |
… | |
… | |
232 | |
226 | |
233 | return Color.pixel; |
227 | return Color.pixel; |
234 | } |
228 | } |
235 | |
229 | |
236 | #ifndef USE_TOON_GET_ROOT_WINDOW |
230 | #ifndef USE_TOON_GET_ROOT_WINDOW |
237 | static Window |
231 | static void |
238 | root_window (Display * display, int screen_number) |
232 | find_root_window (Display *display, int screen_number) |
239 | { |
233 | { |
|
|
234 | if (!root) |
|
|
235 | { |
240 | 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); |
241 | Window real_root_window = RootWindow (display, screen_number); |
238 | root = RootWindow (display, screen_number); |
242 | |
239 | |
243 | if (root) /* root window set via option */ |
|
|
244 | return root; |
|
|
245 | |
|
|
246 | if (SWM_VROOT != None) |
|
|
247 | { |
|
|
248 | Window unused, *windows; |
240 | Window unused, *windows = 0; |
249 | unsigned int count; |
241 | unsigned int count; |
250 | |
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 | } |
251 | if (XQueryTree (display, real_root_window, &unused, &unused, &windows, &count)) |
259 | else if (XQueryTree (display, root, &unused, &unused, &windows, &count)) |
252 | { |
260 | { |
253 | int i; |
261 | int i; |
254 | |
262 | |
255 | for (i = 0; i < count; i++) |
263 | for (i = 0; i < count; i++) |
256 | { |
264 | { |
257 | Atom type; |
|
|
258 | int format; |
|
|
259 | unsigned long nitems, bytes_after_return; |
|
|
260 | unsigned char *virtual_root_window; |
|
|
261 | |
|
|
262 | if (XGetWindowProperty (display, windows[i], SWM_VROOT, |
265 | if (XGetWindowProperty (display, windows[i], SWM_VROOT, |
263 | 0, 1, False, XA_WINDOW, &type, &format, |
266 | 0, 1, False, XA_WINDOW, &type, &format, |
264 | &nitems, &bytes_after_return, |
267 | &nitems, &bytes_after_return, |
265 | &virtual_root_window) == Success) |
268 | &virtual_root_window) == Success |
|
|
269 | && type == XA_WINDOW) |
266 | { |
270 | { |
267 | if (type != None) |
|
|
268 | { |
|
|
269 | if (type == XA_WINDOW) |
|
|
270 | { |
|
|
271 | root = *(Window *)virtual_root_window; |
271 | root = *(Window *)virtual_root_window; |
272 | XFree (windows); |
|
|
273 | XFree (virtual_root_window); |
272 | XFree (virtual_root_window); |
274 | return root; |
|
|
275 | } |
|
|
276 | else |
|
|
277 | fprintf (stderr, "__SWM_VROOT property type mismatch"); |
|
|
278 | } |
273 | break; |
279 | } |
274 | } |
280 | else |
275 | } |
281 | fprintf (stderr, |
|
|
282 | "failed to get __SWM_VROOT property on window 0x%lx", |
|
|
283 | windows[i]); |
|
|
284 | } |
|
|
285 | |
276 | |
286 | if (count) |
|
|
287 | XFree (windows); |
277 | XFree (windows); |
288 | } |
278 | } |
289 | else |
279 | else |
290 | fprintf (stderr, "Can't query tree on root window 0x%lx", |
280 | fprintf (stderr, "Can't query tree on root window 0x%lx", root); |
291 | real_root_window); |
|
|
292 | } |
281 | } |
293 | else |
|
|
294 | /* This shouldn't happen. The Xlib documentation is wrong BTW. */ |
|
|
295 | fprintf (stderr, "Can't intern atom __SWM_VROOT"); |
|
|
296 | |
|
|
297 | return real_root_window; |
|
|
298 | } |
282 | } |
299 | #endif /* USE_TOON_GET_ROOT_WINDOW */ |
283 | #endif /* USE_TOON_GET_ROOT_WINDOW */ |
300 | |
284 | |
301 | void |
285 | void |
302 | InitWindow (void) |
286 | InitWindow (void) |
… | |
… | |
314 | |
298 | |
315 | screen = DefaultScreen (disp); |
299 | screen = DefaultScreen (disp); |
316 | ScreenHeight = DisplayHeight (disp, screen); |
300 | ScreenHeight = DisplayHeight (disp, screen); |
317 | ScreenWidth = DisplayWidth (disp, screen); |
301 | ScreenWidth = DisplayWidth (disp, screen); |
318 | |
302 | |
319 | #ifdef USE_TOON_GET_ROOT_WINDOW |
|
|
320 | real_root = RootWindow(disp, screen); |
|
|
321 | root = ToonGetRootWindow( disp, screen, &real_root ); |
|
|
322 | #else /* USE_TOON_GET_ROOT_WINDOW */ |
|
|
323 | root = root_window (disp, screen); |
303 | find_root_window (disp, screen); |
324 | #endif /* USE_TOON_GET_ROOT_WINDOW */ |
|
|
325 | |
304 | |
326 | gcm = GCBackground; |
305 | gcm = GCBackground; |
327 | gcv.graphics_exposures = True; |
306 | gcv.graphics_exposures = True; |
328 | WinGC = XCreateGC (disp, root, gcm, &gcv); |
307 | WinGC = XCreateGC (disp, root, gcm, &gcv); |
329 | XMapWindow (disp, root); |
308 | XMapWindow (disp, root); |
|
|
309 | |
330 | XSetForeground (disp, WinGC, GetColor (DEF_COLOR)); |
310 | XSetForeground (disp, WinGC, GetColor (DEF_COLOR)); |
331 | |
311 | |
332 | for (e = loglist; e; e = e->next) |
312 | for (e = loglist; e; e = e->next) |
333 | { |
313 | { |
334 | char **missing_charset_list; |
314 | char **missing_charset_list; |
… | |
… | |
364 | if (geom_mask & XNegative) |
344 | if (geom_mask & XNegative) |
365 | win_x = win_x + ScreenWidth - width; |
345 | win_x = win_x + ScreenWidth - width; |
366 | if (geom_mask & YNegative) |
346 | if (geom_mask & YNegative) |
367 | win_y = win_y + ScreenHeight - height; |
347 | win_y = win_y + ScreenHeight - height; |
368 | |
348 | |
369 | if (opt_outline) |
349 | if (opt_outline && !opt_minspace) |
370 | { |
350 | { |
371 | /* adding outline increases the total width and height by 2 |
351 | /* adding outline increases the total width and height by 2 |
372 | pixels each, and offsets the text one pixel right and one |
352 | pixels each, and offsets the text one pixel right and one |
373 | pixel down */ |
353 | pixel down */ |
374 | effect_x_space = effect_y_space = 2; |
354 | effect_x_space = effect_y_space = 2; |
375 | effect_x_offset = effect_y_offset = 1; |
355 | effect_x_offset = effect_y_offset = 1; |
376 | } |
356 | } |
377 | else if (opt_shade) |
357 | else if (opt_shade && !opt_minspace) |
378 | { |
358 | { |
379 | /* adding a shadow increases the space used */ |
359 | /* adding a shadow increases the space used */ |
380 | effect_x_space = abs (SHADE_X); |
360 | effect_x_space = abs (SHADE_X); |
381 | effect_y_space = abs (SHADE_Y); |
361 | effect_y_space = abs (SHADE_Y); |
382 | |
362 | |
… | |
… | |
389 | else |
369 | else |
390 | { |
370 | { |
391 | effect_x_space = effect_y_space = 0; |
371 | effect_x_space = effect_y_space = 0; |
392 | effect_x_offset = effect_y_offset = 0; |
372 | effect_x_offset = effect_y_offset = 0; |
393 | } |
373 | } |
|
|
374 | |
|
|
375 | { |
|
|
376 | struct logfile_entry *e; |
|
|
377 | |
|
|
378 | for (e = loglist; e; e = e->next) |
|
|
379 | e->color = GetColor (e->colorname); |
|
|
380 | } |
394 | |
381 | |
395 | XSelectInput (disp, root, ExposureMask | FocusChangeMask); |
382 | XSelectInput (disp, root, ExposureMask | FocusChangeMask); |
396 | } |
383 | } |
397 | |
384 | |
398 | /* |
385 | /* |
… | |
… | |
1300 | char *transform = NULL; |
1287 | char *transform = NULL; |
1301 | #endif |
1288 | #endif |
1302 | |
1289 | |
1303 | setlocale (LC_CTYPE, ""); /* try to initialize the locale. */ |
1290 | setlocale (LC_CTYPE, ""); /* try to initialize the locale. */ |
1304 | |
1291 | |
1305 | /* window needs to be initialized before colorlookups can be done */ |
|
|
1306 | /* just a dummy to get the color lookups right */ |
|
|
1307 | geom_mask = NoValue; |
|
|
1308 | InitWindow (); |
|
|
1309 | |
|
|
1310 | for (i = 1; i < argc; i++) |
1292 | for (i = 1; i < argc; i++) |
1311 | { |
1293 | { |
1312 | const char *arg = argv[i]; |
1294 | const char *arg = argv[i]; |
1313 | |
1295 | |
1314 | if (arg[0] == '-' && arg[1] != '\0' && arg[1] != ',') |
1296 | if (arg[0] == '-' && arg[1] != '\0' && arg[1] != ',') |
… | |
… | |
1349 | } |
1331 | } |
1350 | else if (!strcmp (arg, "-shade")) |
1332 | else if (!strcmp (arg, "-shade")) |
1351 | opt_shade = 1; |
1333 | opt_shade = 1; |
1352 | else if (!strcmp (arg, "-outline")) |
1334 | else if (!strcmp (arg, "-outline")) |
1353 | opt_outline = 1; |
1335 | opt_outline = 1; |
|
|
1336 | else if (!strcmp (arg, "-minspace")) |
|
|
1337 | opt_minspace = 1; |
1354 | else if (!strcmp (arg, "-noflicker")) |
1338 | else if (!strcmp (arg, "-noflicker")) |
1355 | opt_noflicker = 1; |
1339 | opt_noflicker = 1; |
1356 | else if (!strcmp (arg, "-frame")) |
1340 | else if (!strcmp (arg, "-frame")) |
1357 | opt_frame = 1; |
1341 | opt_frame = 1; |
1358 | else if (!strcmp (arg, "-no-filename")) |
1342 | else if (!strcmp (arg, "-no-filename")) |
… | |
… | |
1442 | perror (fname), exit (1); |
1426 | perror (fname), exit (1); |
1443 | |
1427 | |
1444 | e->desc = xstrdup (desc); |
1428 | e->desc = xstrdup (desc); |
1445 | } |
1429 | } |
1446 | |
1430 | |
1447 | e->color = GetColor (fcolor); |
1431 | e->colorname = fcolor; |
1448 | e->partial = 0; |
1432 | e->partial = 0; |
1449 | e->fontname = fontname; |
1433 | e->fontname = fontname; |
1450 | e->last = NULL; |
1434 | e->last = NULL; |
1451 | e->next = NULL; |
1435 | e->next = NULL; |
1452 | |
1436 | |
… | |
… | |
1604 | " -update allow updates to old partial lines\n" |
1588 | " -update allow updates to old partial lines\n" |
1605 | " -cont string to prefix continued partial lines with\n" |
1589 | " -cont string to prefix continued partial lines with\n" |
1606 | " defaults to \"|| \"\n" |
1590 | " defaults to \"|| \"\n" |
1607 | " -wordwrap wrap long lines at spaces to avoid breaking words\n" |
1591 | " -wordwrap wrap long lines at spaces to avoid breaking words\n" |
1608 | " -shade add shading to font\n" |
1592 | " -shade add shading to font\n" |
|
|
1593 | " -outline add black outline to font\n" |
|
|
1594 | " -minspace force minimum line spacing\n" |
1609 | " -noinitial don't display the last file lines on\n" |
1595 | " -noinitial don't display the last file lines on\n" |
1610 | " startup\n" |
1596 | " startup\n" |
1611 | " -i | -interval seconds interval between checks (fractional\n" |
1597 | " -i | -interval seconds interval between checks (fractional\n" |
1612 | " values o.k.). Default 2.4 seconds\n" |
1598 | " values o.k.). Default 2.4 seconds\n" |
1613 | " -V display version information and exit\n" |
1599 | " -V display version information and exit\n" |