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.3 by pcg, Sun May 5 19:10:39 2002 UTC vs.
Revision 1.7 by pcg, Thu Mar 25 21:07:26 2004 UTC

28#include <fcntl.h> 28#include <fcntl.h>
29#include <errno.h> 29#include <errno.h>
30#include <sys/time.h> 30#include <sys/time.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32#include <sys/types.h> 32#include <sys/types.h>
33#include <locale.h>
33#if HAS_REGEX 34#if HAS_REGEX
34#include <regex.h> 35#include <regex.h>
35#endif 36#endif
36#include <X11/Xlib.h> 37#include <X11/Xlib.h>
38#include <X11/Xatom.h>
37#include <X11/Xutil.h> 39#include <X11/Xutil.h>
38 40
39/* data structures */ 41/* data structures */
40struct logfile_entry { 42struct logfile_entry {
41 char *fname; /* name of file */ 43 char *fname; /* name of file */
52 unsigned long color; 54 unsigned long color;
53}; 55};
54 56
55 57
56/* global variables */ 58/* global variables */
57unsigned int width = STD_WIDTH, listlen = STD_HEIGHT; 59int width = STD_WIDTH, listlen = STD_HEIGHT;
58int win_x = LOC_X, win_y = LOC_Y; 60int win_x = LOC_X, win_y = LOC_Y;
59int w = -1, h = -1, font_width, font_height, font_descent; 61int w = -1, h = -1, font_width, font_height, font_descent;
60int do_reopen; 62int do_reopen;
61struct timeval interval = { 2, 400000 }; /* see Knuth */ 63struct timeval interval = { 2, 400000 }; /* see Knuth */
64XFontSet fontset;
62 65
63/* command line options */ 66/* command line options */
64int opt_noinitial, opt_shade, opt_frame, opt_reverse=0, opt_nofilename, 67int opt_noinitial, opt_shade, opt_frame, opt_reverse, opt_nofilename,
65 geom_mask, reload = 3600; 68 geom_mask, reload = 3600;
66const char *command = NULL, 69const char *command = NULL,
67 *fontname = USE_FONT, *dispname = NULL, *def_color = DEF_COLOR; 70 *fontname = USE_FONT, *dispname = NULL, *def_color = DEF_COLOR;
68 71
69struct logfile_entry *loglist = NULL, *loglist_tail = NULL; 72struct logfile_entry *loglist = NULL, *loglist_tail = NULL;
122 do_reopen = 1; 125 do_reopen = 1;
123} 126}
124 127
125void force_refresh(int dummy) 128void force_refresh(int dummy)
126{ 129{
127 XClearWindow(disp, root); 130 XClearArea(disp, root, win_x, win_y, w, h + font_descent + 2, False);
128 redraw(); 131 redraw();
129} 132}
130 133
131void blank_window(int dummy) 134void blank_window(int dummy)
132{ 135{
133 XClearWindow(disp, root); 136 XClearArea(disp, root, win_x, win_y, w, h + font_descent + 2, False);
134 XFlush(disp); 137 XFlush(disp);
135 exit(0); 138 exit(0);
136} 139}
137 140
138/* X related functions */ 141/* X related functions */
148 else if (!XAllocColor(disp, Attributes.colormap, &Color)) 151 else if (!XAllocColor(disp, Attributes.colormap, &Color))
149 fprintf(stderr, "can't allocate %s\n", ColorName); 152 fprintf(stderr, "can't allocate %s\n", ColorName);
150 return Color.pixel; 153 return Color.pixel;
151} 154}
152 155
156static Window root_window (Display *display, int screen_number)
157{
158 Atom __SWM_VROOT = XInternAtom (display, "__SWM_VROOT", False);
159 Window real_root_window = RootWindow (display, screen_number);
160
161 if (__SWM_VROOT != None)
162 {
163 Window unused, *windows;
164 unsigned int count;
165
166 if (XQueryTree (display, real_root_window, &unused, &unused, &windows,
167 &count))
168 {
169 int i;
170
171 for (i = 0; i < count; i++)
172 {
173 Atom type;
174 int format;
175 unsigned long nitems, bytes_after_return;
176 unsigned char *virtual_root_window;
177
178 if (XGetWindowProperty (display, windows[i], __SWM_VROOT,
179 0, 1, False, XA_WINDOW, &type, &format,
180 &nitems, &bytes_after_return,
181 &virtual_root_window)
182 == Success)
183 {
184 if (type != None)
185 {
186 if (type == XA_WINDOW)
187 {
188 XFree (windows);
189 return (Window)virtual_root_window;
190 }
191 else
192 fprintf (stderr, "__SWM_VROOT property type mismatch");
193 }
194 }
195 else
196 fprintf (stderr,
197 "failed to get __SWM_VROOT property on window 0x%lx",
198 windows[i]);
199 }
200
201 if (count)
202 XFree (windows);
203 }
204 else
205 fprintf (stderr, "Can't query tree on root window 0x%lx",
206 real_root_window);
207 }
208 else
209 /* This shouldn't happen. The Xlib documentation is wrong BTW. */
210 fprintf (stderr, "Can't intern atom __SWM_VROOT");
211
212 return real_root_window;
213}
214
153void InitWindow(void) 215void InitWindow(void)
154{ 216{
155 XGCValues gcv; 217 XGCValues gcv;
156 Font font; 218 Font font;
157 unsigned long gcm; 219 unsigned long gcm;
163 exit(1); 225 exit(1);
164 } 226 }
165 screen = DefaultScreen(disp); 227 screen = DefaultScreen(disp);
166 ScreenHeight = DisplayHeight(disp, screen); 228 ScreenHeight = DisplayHeight(disp, screen);
167 ScreenWidth = DisplayWidth(disp, screen); 229 ScreenWidth = DisplayWidth(disp, screen);
168 root = RootWindow(disp, screen); 230 root = root_window (disp, screen);
169 gcm = GCBackground; 231 gcm = GCBackground;
170 gcv.graphics_exposures = True; 232 gcv.graphics_exposures = True;
171 WinGC = XCreateGC(disp, root, gcm, &gcv); 233 WinGC = XCreateGC(disp, root, gcm, &gcv);
172 XMapWindow(disp, root); 234 XMapWindow(disp, root);
173 XSetForeground(disp, WinGC, GetColor(DEF_COLOR)); 235 XSetForeground(disp, WinGC, GetColor(DEF_COLOR));
187 win_y = win_y + ScreenHeight - h; 249 win_y = win_y + ScreenHeight - h;
188 250
189 XSelectInput(disp, root, ExposureMask|FocusChangeMask); 251 XSelectInput(disp, root, ExposureMask|FocusChangeMask);
190} 252}
191 253
192char * 254char *
193detabificate (char *s) 255detabificate (char *s)
194{ 256{
195 char * out; 257 char * out;
196 int i, j; 258 int i, j;
197 259
198 out = malloc (8 * strlen (s) + 1); 260 out = malloc (8 * strlen (s) + 1);
199 261
200 for(i = 0, j = 0; s[i]; i++) 262 for(i = 0, j = 0; s[i]; i++)
201 { 263 {
202 if (s[i] == '\t') 264 if (s[i] == '\t')
203 do 265 do
204 out[j++] = ' '; 266 out[j++] = ' ';
205 while (j % 8); 267 while (j % 8);
206 else 268 else
207 out[j++] = s[i]; 269 out[j++] = s[i];
208 } 270 }
209 271
210 out[j] = '\0'; 272 out[j] = '\0';
211 return out; 273 return out;
212} 274}
213 275
214/* 276/*
232 maxy -= win_y - font_height; 294 maxy -= win_y - font_height;
233 295
234 for (lin = listlen; lin--;) 296 for (lin = listlen; lin--;)
235 { 297 {
236 char *temp; 298 char *temp;
237 299
238 offset -= font_height; 300 offset -= font_height;
239 301
240 if (offset < miny || offset > maxy) 302 if (offset < miny || offset > maxy)
241 continue; 303 continue;
242 304
243 if (opt_reverse) 305#define LIN ((opt_reverse)?(listlen-lin-1):(lin))
244 temp = detabificate (lines[listlen-lin-1].line);
245 else
246 temp = detabificate (lines[lin].line); 306 temp = detabificate (lines[LIN].line);
247 307
248 if (opt_shade) 308 if (opt_shade)
249 { 309 {
250 XSetForeground (disp, WinGC, black_color); 310 XSetForeground (disp, WinGC, black_color);
311#if 0
312 XmbDrawString (disp, root, fontset, WinGC, win_x + 2, win_y + offset + 2,
313 temp, strlen (temp));
314#endif
251 XDrawString (disp, root, WinGC, win_x + 2, win_y + offset + 2, 315 XDrawString (disp, root, WinGC, win_x + 2, win_y + offset + 2,
252 temp, strlen (temp)); 316 temp, strlen (temp));
253 } 317 }
254 318
255 XSetForeground (disp, WinGC, lines[lin].color); 319 XSetForeground (disp, WinGC, lines[LIN].color);
320#if 0
321 XmbDrawString (disp, root, fontset, WinGC, win_x, win_y + offset,
322 temp, strlen (temp));
323#endif
256 XDrawString (disp, root, WinGC, win_x, win_y + offset, 324 XDrawString (disp, root, WinGC, win_x, win_y + offset,
257 temp, strlen (temp)); 325 temp, strlen (temp));
258
259 free (temp); 326 free (temp);
260 } 327 }
261 328
262 if (opt_frame) { 329 if (opt_frame) {
263 int bot_y = win_y + h + font_descent + 2; 330 int bot_y = win_y + h + font_descent + 2;
293#endif 360#endif
294 361
295 362
296/* 363/*
297 * This routine should read 'width' characters and not more. However, 364 * This routine should read 'width' characters and not more. However,
298 * we really want to read width + 1 charachters if the last char is a '\n', 365 * we really want to read width + 1 characters if the last char is a '\n',
299 * which we should remove afterwards. So, read width+1 chars and ungetc 366 * which we should remove afterwards. So, read width+1 chars and ungetc
300 * the last character if it's not a newline. This means 'string' must be 367 * the last character if it's not a newline. This means 'string' must be
301 * width + 2 wide! 368 * width + 2 wide!
302 */ 369 */
303int lineinput(char *string, int slen, FILE *f) 370int lineinput(char *string, int slen, FILE *f)
440 strcpy(lines[lin].line, "~"); 507 strcpy(lines[lin].line, "~");
441 lines[lin].color = GetColor(def_color); 508 lines[lin].color = GetColor(def_color);
442 } 509 }
443 510
444 if (!opt_noinitial) 511 if (!opt_noinitial)
512 {
445 while (lineinput(buf, buflen, loglist->fp) != 0) { 513 while (lineinput(buf, buflen, loglist->fp) != 0) {
446 SCROLL_UP(lines, listlen); 514 SCROLL_UP(lines, listlen);
447 /* print the next line */ 515 /* print the next line */
448 strcpy(lines[listlen - 1].line, buf); 516 strcpy(lines[listlen - 1].line, buf);
449 } 517 }
518
519 redraw ();
520 }
450 521
451 for (;;) { 522 for (;;) {
452 int need_update = 0; 523 int need_update = 0;
453 struct logfile_entry *current; 524 struct logfile_entry *current;
454 static struct logfile_entry *lastprinted = NULL; 525 static struct logfile_entry *lastprinted = NULL;
552 int i; 623 int i;
553 int opt_daemonize = 0; 624 int opt_daemonize = 0;
554#if HAS_REGEX 625#if HAS_REGEX
555 char *transform = NULL; 626 char *transform = NULL;
556#endif 627#endif
628
629 setlocale (LC_CTYPE, ""); /* try to initialize the locale. */
557 630
558 /* window needs to be initialized before colorlookups can be done */ 631 /* window needs to be initialized before colorlookups can be done */
559 /* just a dummy to get the color lookups right */ 632 /* just a dummy to get the color lookups right */
560 geom_mask = NoValue; 633 geom_mask = NoValue;
561 InitWindow(); 634 InitWindow();
770 if (setsid() == -1) 843 if (setsid() == -1)
771 return -1; 844 return -1;
772 845
773 return 0; 846 return 0;
774} 847}
775

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines