home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <values.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/time.h>
- #include <suntool/sunview.h>
- #include <suntool/frame.h>
- #include <suntool/textsw.h>
- #include <sunwindow/notify.h>
-
- /*
- * SunView size definitions. I shouldn't have to define these, but
- * there is no way to query SunView for them.
- */
- #define LMARGIN 5 /* left frame margin */
- #define RMARGIN 5 /* right frame margin */
- #define BMARGIN 5 /* bottom frame margin */
- #define SMARGIN 5 /* subwindow spacing */
-
- Frame frame;
- int files, updating = 0;
- Textsw text[16]; /* text subwindows */
- Menu menu[16]; /* menus for each subwindow */
- char *file[16]; /* filenames */
- off_t length[16]; /* file lengths */
- char alert[16]; /* flags: blink icon on update? */
-
- /*
- * Construct the icons.
- * None.icon is displayed when there are no new files; otherwise,
- * new1.icon and new2.icon are toggled once a second.
- */
- static short none_icon_i[] = {
- #include "none.icon"
- };
- mpr_static(none_icon_p, 64, 64, 1, none_icon_i);
-
- static short new1_icon_i[] = {
- #include "new1.icon"
- };
- mpr_static(new1_icon_p, 64, 64, 1, new1_icon_i);
-
- static short new2_icon_i[] = {
- #include "new2.icon"
- };
- mpr_static(new2_icon_p, 64, 64, 1, new2_icon_i);
-
- Icon ikes[3];
- int inum = 1;
- int newstuff;
-
- main(argc, argv)
- char **argv;
- {
- ikes[0] = icon_create(ICON_IMAGE, &none_icon_p, 0);
- ikes[1] = icon_create(ICON_IMAGE, &new1_icon_p, 0);
- ikes[2] = icon_create(ICON_IMAGE, &new2_icon_p, 0);
-
- frame = window_create(NULL, FRAME,
- FRAME_LABEL, "LUMBERJACK 1.0 by Steven Grimm (koreth@ssyx.ucsc.edu)",
- FRAME_ARGC_PTR_ARGV, &argc, argv,
- FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
- FRAME_ICON, ikes[0],
- WIN_ERROR_MSG, "Couldn't open window",
- 0);
-
- parse_args(argc, argv);
- create_subwindows();
- set_window_sizes();
- load_files();
-
- newstuff = 0;
- window_set(frame, FRAME_ICON, ikes[0], 0);
-
- set_notifier();
-
- window_main_loop(frame);
- }
-
- /*
- * Create all the necessary subwindows.
- */
- create_subwindows()
- {
- int i, domenu();
-
- for (i=0; i<files; i++)
- {
- menu[i] = menu_create(MENU_TITLE_ITEM, file[i],
- MENU_ACTION_ITEM, "Close", domenu,
- 0);
- text[i] = window_create(frame, TEXTSW,
- WIN_ERROR_MSG, "Couldn't create subwindow",
- WIN_IGNORE_PICK_EVENT, WIN_RESIZE,
- TEXTSW_DISABLE_CD, TRUE,
- TEXTSW_DISABLE_LOAD, TRUE,
- TEXTSW_INSERT_MAKES_VISIBLE, TEXTSW_ALWAYS,
- TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,
- TEXTSW_MENU, menu[i],
- 0);
- }
- }
-
- /*
- * Set all the window sizes. This gets called whenever the base
- * frame gets resized, and once at initialization.
- *
- * For now, all the subwindows are assumed to be of equal size.
- */
- set_window_sizes()
- {
- int i, fr_height, fr_width, ts_height, ts_width;
-
- fr_height = (int)window_get(frame, WIN_HEIGHT) -
- (int)window_get(frame, WIN_TOP_MARGIN);
- fr_width = (int)window_get(frame, WIN_WIDTH) -
- LMARGIN - RMARGIN;
- ts_height = fr_height/files - SMARGIN;
- ts_width = fr_width;
-
- for (i=0; i<files; i++)
- {
- window_set(text[i],
- WIN_HEIGHT, ts_height,
- WIN_WIDTH, ts_width,
- 0);
- if (i)
- window_set(text[i], WIN_BELOW, text[i-1], 0);
- }
- }
-
- /*
- * Parse command line arguments.
- * For now, this is just a list of filenames.
- */
- parse_args(c, v)
- char **v;
- {
- int i, nflag = 0;
-
- files = 0;
- for (i=1; i<c; i++)
- {
- if (! strcmp(v[i], "-n"))
- nflag = 1;
- else if (access(v[i], R_OK) == 0)
- {
- file[files] = v[i];
- length[files] = MAXINT;
- alert[files] = !nflag;
- nflag = 0;
- if (++files == 16)
- break;
- }
- else
- perror(v[i]);
- }
- if (! files)
- exit(1);
- }
-
- /*
- * Load all the files into their windows, and place the cursors at the
- * infinity position. This gets called once every second.
- */
- load_files()
- {
- int i;
- struct stat st;
-
- for (i=0; i<files; i++)
- {
- if (stat(file[i], &st) < 0 || access(file[i], R_OK))
- {
- kill_file(i);
- continue;
- }
- if (st.st_size == length[i])
- continue;
- if (st.st_size < length[i]) /* file has gotten smaller */
- window_set(text[i], TEXTSW_FILE, file[i], 0);
- else if (st.st_size > length[i])
- {
- char *buf;
- int fd, bsiz;
-
- buf = (char *)malloc(bsiz = (st.st_size - length[i]));
- fd = open(file[i], O_RDONLY);
- if (fd < 0)
- {
- filerror:
- free(buf);
- kill_file(i);
- }
- if (lseek(fd, length[i], L_SET) < 0)
- goto filerror;
- if (read(fd, buf, bsiz) < 0)
- goto filerror;
-
- window_set(text[i],
- TEXTSW_INSERTION_POINT, TEXTSW_INFINITY,
- 0);
- textsw_insert(text[i], buf, bsiz);
- textsw_possibly_normalize(text[i], (Textsw_index)length[i]);
- free(buf);
- }
- length[i] = st.st_size;
- if (alert[i])
- newstuff++;
- }
- if (newstuff)
- if ((int)window_get(frame, FRAME_CLOSED))
- {
- inum ^= 3;
- window_set(frame, FRAME_ICON, ikes[inum], 0);
- }
- else
- {
- newstuff = 0;
- window_set(frame, FRAME_ICON, ikes[0], 0);
- }
- }
-
- /*
- * Handle events.
- */
- Notify_value
- event(window, event, arg, type)
- Window window;
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
- {
- Notify_value value;
-
- value = notify_next_event_func(window, event, arg, type);
- if (event_id(event) == WIN_RESIZE)
- set_window_sizes();
- return(value);
- }
-
- /*
- * Handle a menu selection.
- */
- domenu(m, mi)
- Menu m;
- Menu_item mi;
- {
- int win;
-
- for (win = 0; win < files; win++)
- if (menu[win] == m)
- break;
- if (win == files)
- return;
- if ((int)menu_get(m, MENU_SELECTED) == 2)
- kill_file(win);
- }
-
- /*
- * Kill a file, either because we got an error reading it or because
- * the user said so.
- */
- kill_file(num)
- int num;
- {
- int i;
-
- menu_destroy(menu[num]);
- window_destroy(text[num]);
- if (num != files-1)
- {
- for (i = num+1; i < files; i++)
- {
- menu[i-1] = menu[i];
- text[i-1] = text[i];
- file[i-1] = file[i];
- length[i-1] = length[i];
- alert[i-1] = alert[i];
- }
- }
- if (num == 0)
- window_set(text[0], WIN_Y, 0, 0);
- if (--files == 0)
- exit(0);
- set_window_sizes();
- }
-
- /*
- * Set up a timer. It checks all the files once a second.
- * Also, tell the notifier what to do about resizes and so forth.
- */
- set_notifier()
- {
- static struct itimerval timer; /* this is our handle */
-
- bzero(&timer, sizeof(timer));
- timer.it_interval.tv_sec = 1;
- timer.it_value.tv_sec = 1;
- notify_set_itimer_func(&timer, load_files, ITIMER_REAL, &timer, NULL);
- notify_interpose_event_func(frame, event, NOTIFY_SAFE);
- }
-