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.6 by pcg, Tue Oct 7 13:02:57 2003 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 */
57int 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, 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,
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#define LIN ((opt_reverse)?(listlen-lin-1):(lin)) 305#define LIN ((opt_reverse)?(listlen-lin-1):(lin))
244 temp = detabificate (lines[LIN].line); 306 temp = detabificate (lines[LIN].line);
245 307
246 if (opt_shade) 308 if (opt_shade)
247 { 309 {
248 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
249 XDrawString (disp, root, WinGC, win_x + 2, win_y + offset + 2, 315 XDrawString (disp, root, WinGC, win_x + 2, win_y + offset + 2,
250 temp, strlen (temp)); 316 temp, strlen (temp));
251 } 317 }
252 318
253 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
254 XDrawString (disp, root, WinGC, win_x, win_y + offset, 324 XDrawString (disp, root, WinGC, win_x, win_y + offset,
255 temp, strlen (temp)); 325 temp, strlen (temp));
256
257 free (temp); 326 free (temp);
258 } 327 }
259 328
260 if (opt_frame) { 329 if (opt_frame) {
261 int bot_y = win_y + h + font_descent + 2; 330 int bot_y = win_y + h + font_descent + 2;
291#endif 360#endif
292 361
293 362
294/* 363/*
295 * This routine should read 'width' characters and not more. However, 364 * This routine should read 'width' characters and not more. However,
296 * 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',
297 * 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
298 * 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
299 * width + 2 wide! 368 * width + 2 wide!
300 */ 369 */
301int lineinput(char *string, int slen, FILE *f) 370int lineinput(char *string, int slen, FILE *f)
438 strcpy(lines[lin].line, "~"); 507 strcpy(lines[lin].line, "~");
439 lines[lin].color = GetColor(def_color); 508 lines[lin].color = GetColor(def_color);
440 } 509 }
441 510
442 if (!opt_noinitial) 511 if (!opt_noinitial)
512 {
443 while (lineinput(buf, buflen, loglist->fp) != 0) { 513 while (lineinput(buf, buflen, loglist->fp) != 0) {
444 SCROLL_UP(lines, listlen); 514 SCROLL_UP(lines, listlen);
445 /* print the next line */ 515 /* print the next line */
446 strcpy(lines[listlen - 1].line, buf); 516 strcpy(lines[listlen - 1].line, buf);
447 } 517 }
518
519 redraw ();
520 }
448 521
449 for (;;) { 522 for (;;) {
450 int need_update = 0; 523 int need_update = 0;
451 struct logfile_entry *current; 524 struct logfile_entry *current;
452 static struct logfile_entry *lastprinted = NULL; 525 static struct logfile_entry *lastprinted = NULL;
550 int i; 623 int i;
551 int opt_daemonize = 0; 624 int opt_daemonize = 0;
552#if HAS_REGEX 625#if HAS_REGEX
553 char *transform = NULL; 626 char *transform = NULL;
554#endif 627#endif
628
629 setlocale (LC_CTYPE, ""); /* try to initialize the locale. */
555 630
556 /* window needs to be initialized before colorlookups can be done */ 631 /* window needs to be initialized before colorlookups can be done */
557 /* just a dummy to get the color lookups right */ 632 /* just a dummy to get the color lookups right */
558 geom_mask = NoValue; 633 geom_mask = NoValue;
559 InitWindow(); 634 InitWindow();
768 if (setsid() == -1) 843 if (setsid() == -1)
769 return -1; 844 return -1;
770 845
771 return 0; 846 return 0;
772} 847}
773

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines