source: trunk/athena/etc/console/console.c @ 12243

Revision 12243, 18.4 KB checked in by ghudson, 26 years ago (diff)
Move console sources here from athena/bin/dash/src/console, and autoconfiscate.
Line 
1/* Copyright 1990, 1991, 1998 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16static const char rcsid[] = "$Id: console.c,v 1.1 1998-12-17 16:26:02 ghudson Exp $";
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <sys/types.h>
21#include <fcntl.h>
22#include <ctype.h>
23#include <sys/time.h>
24#include <sys/file.h>
25#include <sys/stat.h>
26#include <errno.h>
27#include <signal.h>
28#include <syslog.h>
29#include <Jets/Jets.h>
30#include <Jets/Window.h>
31#include <Jets/Button.h>
32#include <Jets/Label.h>
33#include <Jets/Form.h>
34#include <Jets/ScrollBar.h>
35#include <Jets/TextDisplay.h>
36#include <Jets/Arrow.h>
37#include <X11/Xresource.h>
38
39#ifndef CONSOLEDEFAULTS
40#define CONSOLEDEFAULTS "/etc/athena/login/Console"
41#endif
42
43#define XENV "XENVIRONMENT"
44#define CONSOLEFILE "/var/athena/console.log"
45
46extern int DEBUG;
47
48static XrmOptionDescRec opTable[] = {
49{"+rv",         "*reverseVideo", XrmoptionNoArg,        (caddr_t) "off"},
50{"-background", "*background",  XrmoptionSepArg,        (caddr_t) NULL},
51{"-bd",         "*window.borderColor", XrmoptionSepArg, (caddr_t) NULL},
52{"-bg",         "*background",  XrmoptionSepArg,        (caddr_t) NULL},
53{"-bordercolor","*borderColor", XrmoptionSepArg,        (caddr_t) NULL},
54{"-borderwidth","*window.borderWidth", XrmoptionSepArg, (caddr_t) NULL},
55{"-bw",         "*window.borderWidth", XrmoptionSepArg, (caddr_t) NULL},
56{"-display",    ".display",     XrmoptionSepArg,        (caddr_t) NULL},
57{"-fg",         "*foreground",  XrmoptionSepArg,        (caddr_t) NULL},
58{"-fn",         "*font",        XrmoptionSepArg,        (caddr_t) NULL},
59{"-font",       "*font",        XrmoptionSepArg,        (caddr_t) NULL},
60{"-foreground", "*foreground",  XrmoptionSepArg,        (caddr_t) NULL},
61{"-geometry",   "*window.geometry", XrmoptionSepArg,    (caddr_t) NULL},
62{"-icongeometry", "*iconWindow.geometry", XrmoptionSepArg, (caddr_t) NULL},
63{"-name",       ".name",        XrmoptionSepArg,        (caddr_t) NULL},
64{"-reverse",    "*reverseVideo", XrmoptionNoArg,        (caddr_t) "on"},
65{"-rv",         "*reverseVideo", XrmoptionNoArg,        (caddr_t) "on"},
66{"-xrm",        NULL,           XrmoptionResArg,        (caddr_t) NULL},
67{"-appdefs",    ".appDefs",     XrmoptionSepArg,        (caddr_t) NULL},
68{"-f",          ".appDefs",     XrmoptionSepArg,        (caddr_t) NULL},
69{"-blink",      ".frequency",   XrmoptionSepArg,        (caddr_t) NULL},
70{"-unmap",      ".autoUnmap",   XrmoptionSepArg,        (caddr_t) NULL},
71{"-map",        "*window.mapped", XrmoptionNoArg,       (caddr_t) "True"},
72{"+map",        "*window.mapped", XrmoptionNoArg,       (caddr_t) "False"},
73{"-input",      ".input",       XrmoptionSepArg,        (caddr_t) NULL},
74{"-inputfd",    ".inputfd",     XrmoptionSepArg,        (caddr_t) NULL},
75{"-nostdin",    ".nostdin",     XrmoptionNoArg,         (caddr_t) "True"},
76{"-iconic",     "*window.iconic", XrmoptionNoArg,       (caddr_t) "True"},
77{"+iconic",     "*window.iconic", XrmoptionNoArg,       (caddr_t) "False"},
78{"-notimestamp",".timestamp",   XrmoptionNoArg,         (caddr_t) "False"},
79{"-timestamp",  ".timestamp",   XrmoptionNoArg,         (caddr_t) "True"},
80{"-hidelabel",  "*hideLabel.label", XrmoptionSepArg,    (caddr_t) NULL},
81{"-title",      "*title.label", XrmoptionSepArg,        (caddr_t) NULL},
82{"-hideproc",   "*hideButton.activateProc", XrmoptionSepArg, (caddr_t) NULL},
83{"-cc",         "*textDisplay.charClass", XrmoptionSepArg, (caddr_t) NULL},
84{"-titlebar",   "*window.title",XrmoptionSepArg,        (caddr_t) NULL},
85{"-nosession",  "*showCommand", XrmoptionNoArg,         (caddr_t) "false"},
86{"-global",     "*global",      XrmoptionNoArg,         (caddr_t) "true"},
87{"-autoscroll", ".autoscroll",  XrmoptionNoArg,         (caddr_t) "True"},
88{"-noautoscroll",".autoscroll", XrmoptionNoArg,         (caddr_t) "False"},
89{"-file",       ".file",        XrmoptionSepArg,        (caddr_t) ""},
90{"-debug",      ".debug",       XrmoptionNoArg,         (caddr_t) "true"},
91};
92
93typedef struct _MyResources
94{
95  int frequency, autoUnmap;
96  char *input;
97  int inputfd;
98  Boolean timestamp, autoscroll, nostdin;
99  char *file;
100  Boolean debug;
101} MyResources;
102
103typedef struct _MyResources *MyResourcesPtr;
104
105MyResources parms;
106
107#define offset(field) XjOffset(MyResourcesPtr,field)
108
109static XjResource appResources[] =
110{
111  { "frequency", "Frequency", XjRInt, sizeof(int),
112      offset(frequency), XjRInt, (caddr_t)1000 },
113  { "autoUnmap", "AutoUnmap", XjRInt, sizeof(int),
114      offset(autoUnmap), XjRInt, (caddr_t)0 },
115  { "input", "Input", XjRString, sizeof(char *),
116      offset(input), XjRString, (caddr_t)"" },
117  { "inputfd", "Inputfd", XjRInt, sizeof(int),
118      offset(inputfd), XjRInt, (caddr_t)0 },
119  { "nostdin", "Nostdin", XjRBoolean, sizeof(Boolean),
120      offset(nostdin), XjRBoolean, (caddr_t) False },
121  { "timestamp", "Timestamp", XjRBoolean, sizeof(Boolean),
122      offset(timestamp), XjRBoolean, (caddr_t) True },
123  { "autoscroll", "Autoscroll", XjRBoolean, sizeof(Boolean),
124      offset(autoscroll), XjRBoolean, (caddr_t) True },
125  { "file", "File", XjRString, sizeof(char *),
126      offset(file), XjRString, (caddr_t)CONSOLEFILE },
127  { "debug", "Debug", XjRBoolean, sizeof(Boolean),
128      offset(debug), XjRBoolean, (caddr_t) False },
129};
130
131#undef offset
132
133#define INPUTSIZE 1024
134char inputbuf[INPUTSIZE];
135
136#define BUFSIZE 16384 /* must be at least two times as big as INPUTSIZE */
137char *text;
138int length;
139
140
141#define HUP 0
142#define FPE 1
143#define USR1 2
144#define USR2 3
145#define NUMSIGS 4
146int sigflags[NUMSIGS];
147int val = 0;
148Jet root;
149WindowJet iconWindow;
150LabelJet icon;
151WindowJet win;
152ScrollBarJet sj;
153TextDisplayJet tj;
154int inverted = False, blinking = False, timerid;
155int unmaptimerid;
156
157
158static int loadFile(filename, info, max)
159     char *filename, *info;
160     int max;
161{
162    int fd, size;
163    struct stat buf;
164    int num;
165    char errtext[100];
166    char *errfmt = "error %d %s `%s'";
167
168    if (-1 == (fd = open(filename, O_RDONLY, 0)))
169      {
170        sprintf(errtext, errfmt, errno, "opening", filename);
171        XjWarning(errtext);
172        return 0;
173      }
174
175    if (-1 == fstat(fd, &buf)) /* could only return EIO */
176      {
177        sprintf(errtext, errfmt, errno, "in fstat for", filename);
178        XjWarning(errtext);
179        close(fd);
180        return 0;
181      }
182
183    size = (int)buf.st_size;
184
185    if (-1 == (num = read(fd, info, MIN(size, max - 1))))
186      {
187        sprintf(errtext, errfmt, errno, "reading", filename);
188        XjWarning(errtext);
189        close(fd);
190        return 0;
191      }
192    close(fd);
193
194    info[num] = '\0';
195    return num;
196}
197
198
199static void saveFile(filename, info, length)
200     char *filename, *info;
201     int length;
202{
203  int fd;
204  char errtext[100];
205  char *errfmt = "error %d %s `%s'";
206
207  if (-1 == (fd = open(filename, O_TRUNC | O_CREAT | O_WRONLY, 0644)))
208    {
209      sprintf(errtext, errfmt, errno, "opening", filename);
210      XjWarning(errtext);
211      return;
212    }
213
214  if (length != write(fd, info, length))
215    {
216      sprintf(errtext, errfmt, errno, "writing", filename);
217      XjWarning(errtext);
218      close(fd); /* I doubt it. */
219      return;
220    }
221
222  close(fd);
223}
224
225
226int hide(fromJet, what, data)
227     Jet fromJet;
228     char *what;
229     caddr_t data;
230     /*ARGSUSED*/
231{
232  UnmapWindow(win);
233  return 0;
234}
235
236
237void resetunmaptimer()
238{
239  if (parms.autoUnmap != 0)
240    {
241      if (unmaptimerid != 0)
242        (void)XjRemoveWakeup(unmaptimerid);
243      unmaptimerid = XjAddWakeup(hide, 0, 1000 * parms.autoUnmap);
244    }
245}
246
247
248int scroll(fromJet, increment, data)
249     Jet fromJet;
250     int increment;
251     caddr_t data;
252     /*ARGSUSED*/
253{
254  int cl, vl;
255
256  resetunmaptimer();
257  cl = CountLines(tj);
258  vl = VisibleLines(tj);
259  val = GetScrollBarValue(sj);
260  if ((increment > 0  &&  val < cl - vl)
261      ||  (increment < 0   &&  val > 0))
262    {
263      val += increment;
264      SetScrollBar(sj, 0, MAX(0, cl - 1), vl, val);
265      SetLine(tj, val);
266    }
267  return 0;
268}
269
270
271int newvalue(fromJet, nothing, data)
272     Jet fromJet;
273     int nothing;
274     caddr_t data;
275     /*ARGSUSED*/
276{
277  resetunmaptimer();
278  SetLine(tj, val = GetScrollBarValue((ScrollBarJet) fromJet));
279  return 0;
280}
281
282
283int textscroll(fromJet, nothing, data)
284     Jet fromJet;
285     int nothing;
286     caddr_t data;
287     /*ARGSUSED*/
288{
289  int cl, vl;
290
291  resetunmaptimer();
292  cl = CountLines(tj);
293  vl = VisibleLines(tj);
294  val = TopLine(tj);
295  SetScrollBar(sj, 0, MAX(0, cl - 1), vl, val);
296  return 0;
297}
298
299
300int textresize(fromJet, nothing, data)
301     Jet fromJet;
302     int nothing;
303     caddr_t data;
304     /*ARGSUSED*/
305{
306  int cl, vl;
307
308  resetunmaptimer();
309  cl = CountLines(tj);
310  vl = VisibleLines(tj);
311
312  if ((val != 0) && (val > cl - vl))
313    {
314      if (parms.autoscroll)
315        {
316          val = MAX(0, cl - vl);
317
318          SetLine(tj, val);
319        }
320    }
321
322  SetScrollBar(sj, 0, MAX(0, cl - 1), vl, val);
323  return 0;
324}
325
326
327int delete(fromJet, what, data)
328     Jet fromJet;
329     char *what;
330     caddr_t data;
331     /*ARGSUSED*/
332{
333  XjDestroyJet(fromJet);
334  XCloseDisplay(root->core.display);
335  XjExit(0);
336  return 0;                             /* For linting... */
337}
338
339
340void blinkoff()
341{
342  if (blinking)
343    {
344      if (inverted)
345        {
346          inverted = !inverted;
347          setIcon(icon, Center, inverted);
348        }
349
350      (void)XjRemoveWakeup(timerid);
351      blinking = False;
352    }
353}
354
355
356int mapnotify(fromJet, what, data)
357     Jet fromJet;
358     char *what;
359     caddr_t data;
360     /*ARGSUSED*/
361{
362  blinkoff();
363  return 0;
364}
365
366
367void OurMapWindow(who)
368     WindowJet who;
369{
370  blinkoff();
371  resetunmaptimer();
372  MapWindow(who, True);
373}
374
375
376int blink(info, id)
377     int info, id;
378     /*ARGSUSED*/
379{
380  inverted = !inverted;
381  setIcon(icon, Center, inverted);
382  timerid = XjAddWakeup(blink, 0, MAX(100, parms.frequency));
383  return 0;
384}
385
386
387int appendToBuffer(what, howmuch)
388     char *what;
389     int howmuch;
390{
391  int moved = 0;
392
393  if (howmuch == 0)             /* if nothing to copy, return */
394    return 0;
395
396  /*
397   * If there's not enough room to copy in whatever was asked for, then
398   * chop off the beginning of the text, using bcopy...
399   */
400  if (BUFSIZE - length <= howmuch)
401    {
402      char *c;
403
404      c = text + MIN(INPUTSIZE, length);
405      while ((c < text + length) && *c != '\0' && *c != '\n')
406        c++;
407      if (*c != '\n')           /* if this is a looooong line, screw it. */
408        c = text + MIN(INPUTSIZE, length);
409      else
410        c++;
411
412      moved = c - text;
413      length -= moved;
414
415      memmove(text, c, length);
416    }
417
418  memcpy(text + length, what, howmuch);
419  length += howmuch;
420  text[length] = '\0';          /* Null terminate the string... */
421                                /* WARNING:  This can overflow!  Why? */
422  return moved;
423}
424
425
426int input(fd, pfd)
427     int fd;
428     int *pfd;
429     /*ARGSUSED*/
430{
431  int redo = 0;
432  int cl, vl, l;
433  char ctrl[2];
434  int i = 0, j, err;
435  static int eol = 1;
436
437  ctrl[0] = '^';
438  l = read(*pfd, inputbuf, INPUTSIZE);
439
440  if (l < 0 && errno != EIO && errno != EINTR)
441    {
442      err = errno;
443      syslog(LOG_ERR, "Error reading from fd %d: %m", *pfd);
444      XjReadCallback((XjCallbackProc)NULL, *pfd, (caddr_t) pfd);
445      sprintf(inputbuf, "Error reading from fd %d: %s\n", *pfd,
446              strerror(err));
447      l = strlen(inputbuf);
448    }
449
450  if (l > 0)
451    {
452      while (i < l)
453        {
454          if (eol && parms.timestamp)
455            {
456              struct timeval now;
457              time_t timet;
458              char *timestr;
459
460              gettimeofday(&now, NULL);
461              timet = (time_t) now.tv_sec;
462              timestr = (char *) ctime(&timet);
463              redo += appendToBuffer(&timestr[11], 5);
464              redo += appendToBuffer(" ", 1);
465            }
466
467          eol = 0;
468          j = i;
469          while (j < l && !eol)
470            {
471              if (iscntrl(inputbuf[j]))
472                {
473                  redo += appendToBuffer(&inputbuf[i], j - i);
474                  i = j + 1;
475
476                  switch(inputbuf[j])
477                    {
478                    case 7: /* bell compression option... */
479                      XBell(root->core.display, 0);
480                    case 0:
481                    case 13:
482                      break;
483                    case '\n':
484                      eol = 1;
485                    case '\t':
486                      redo += appendToBuffer(&inputbuf[j], 1);
487                      break;
488                    default:
489                      ctrl[1] = inputbuf[j] | 64;
490                      redo += appendToBuffer(ctrl, 2);
491                      break;
492                    }
493                }
494              j++;
495            }
496          redo += appendToBuffer(&inputbuf[i], j - i);
497          i = j;
498        }
499      if (!redo)
500        AddText(tj);            /* ??? */
501      else
502        MoveText(tj, text, redo);
503
504      cl = CountLines(tj);
505      vl = VisibleLines(tj);
506
507      if (parms.autoscroll)
508        {
509          val = MAX(0, cl - vl);
510
511          SetScrollBar(sj, 0, MAX(cl - 1, 0), vl, val);
512          SetLine(tj, val);
513        }
514     
515      if (!WindowMapped((WindowJet)win))
516        {
517          if (!WindowMapped(iconWindow))
518            OurMapWindow((WindowJet)win); /* we're hidden, not iconified */
519          else
520            {
521              if (!blinking)
522                {
523                  blinking = True;
524                  blink(0, 0);
525                }
526            }
527        }
528      else
529        {
530          resetunmaptimer();
531          if (WindowVisibility(win) != VisibilityUnobscured)
532            XRaiseWindow(win->core.display, win->core.window); /* ICCCM ok */
533        }
534    }
535  return 0;
536}
537
538void sighandler(sig)
539     int sig;
540{
541  switch(sig)
542    {
543    case SIGHUP:
544      sigflags[HUP] = 1;
545      break;
546    case SIGFPE:
547      sigflags[FPE] = 1;
548      break;
549    case SIGUSR1:
550      sigflags[USR1] = 1;
551      break;
552    case SIGUSR2:
553      sigflags[USR2] = 1;
554      break;
555    }
556  return;
557}
558
559
560XjCallbackRec callbacks[] =
561{
562  { "newvalue", newvalue },
563  { "textresize", textresize },
564  { "textscroll", textscroll },
565  { "delete", delete },
566  { "hide", hide },
567  { "mapnotify", mapnotify },
568  { "scroll", scroll },
569};
570
571
572static int checkSignals()
573{
574  int sigs;
575  int cl, vl;
576  int ret_code=0;
577
578  do
579    {
580      sigs = 0;
581
582      if (sigflags[FPE])
583        {
584          sigs++;
585          sigflags[FPE] = 0;
586          text[0] = '\0';
587          length = 0;
588          saveFile(parms.file, text, length);
589
590          blinkoff();
591          if (WindowMapped(win))
592            UnmapWindow(win);
593
594          SetText(tj, text);
595
596          cl = CountLines(tj);
597          vl = VisibleLines(tj);
598
599          val = MAX(0, cl - vl);
600
601          SetScrollBar(sj, 0, MAX(cl - 1, 0), vl, val);
602          SetLine(tj, val);
603          XFlush(tj->core.display);
604        }
605
606      if (sigflags[USR1])
607        {
608          sigs++;
609          sigflags[USR1] = 0;
610          if (!WindowMapped((WindowJet)win))
611            {
612              OurMapWindow((WindowJet)win);
613              XFlush(win->core.display);
614            }
615          else
616            if (WindowVisibility(win) != VisibilityUnobscured)
617              {
618                XRaiseWindow(win->core.display, win->core.window); /* ICCCM ok */
619                XFlush(win->core.display);
620              }
621        }
622
623      if (sigflags[USR2])
624        {
625          sigs++;
626          sigflags[USR2] = 0;
627          if (WindowMapped(win))
628            {
629              UnmapWindow(win);
630              XFlush(win->core.display);
631            }
632        }
633
634      if (sigflags[HUP])
635        {
636          sigs++;
637          sigflags[HUP] = 0;
638          saveFile(parms.file, text, length);
639          XCloseDisplay(root->core.display);
640          XjExit(0);
641        }
642      ret_code += sigs;
643    }
644  while(sigs);
645  return ret_code;
646}
647
648
649fatal(display)
650     Display *display;
651     /*ARGSUSED*/
652{
653  XjExit(1);
654}
655
656
657main(argc, argv)
658     int argc;
659     char **argv;
660{
661  Jet w, b, f;
662  int cl, vl, i;
663  int zero = 0;
664  int auxinput = -1;
665  int size=0;
666  char *envvar;
667  struct stat buf;
668  struct sigaction act;
669  sigemptyset(&act.sa_mask);
670  act.sa_flags = 0;
671
672  openlog("console", 0, LOG_USER);
673
674  for (i = 0; i < NUMSIGS; i++)
675    sigflags[i] = 0;
676
677  act.sa_handler= sighandler;
678  (void) sigaction(SIGHUP, &act, NULL);
679  (void) sigaction(SIGFPE, &act, NULL);
680  (void) sigaction(SIGUSR1, &act, NULL);
681  (void) sigaction(SIGUSR2, &act, NULL);
682
683  if (getenv(XENV) == NULL)
684    {
685      envvar = malloc(strlen(XENV) + strlen(CONSOLEDEFAULTS) + 2);
686      if (!envvar)
687        {
688          fprintf(stderr, "malloc failed!  Aborting.\n");
689          exit(1);
690        }
691      sprintf(envvar, "%s=%s", XENV, CONSOLEDEFAULTS);
692      putenv(envvar);
693    }
694
695  root = XjCreateRoot(&argc, argv, "Console", NULL,
696                      opTable, XjNumber(opTable));
697
698  (void) XSetIOErrorHandler(fatal);
699
700  XjLoadFromResources(NULL,
701                      NULL,
702                      programClass,
703                      programName,
704                      appResources,
705                      XjNumber(appResources),
706                      (caddr_t) &parms);
707
708  DEBUG = parms.debug;
709
710  XjRegisterCallbacks(callbacks, XjNumber(callbacks));
711
712  iconWindow = (WindowJet) XjVaCreateJet("iconWindow",
713                                         windowJetClass, root, NULL, NULL);
714  icon = (LabelJet) XjVaCreateJet("icon",
715                                  labelJetClass, iconWindow, NULL, NULL);
716  XjRealizeJet(root);
717
718  win = (WindowJet) XjVaCreateJet("window", windowJetClass, root,
719                                  XjNiconWindow, iconWindow,
720                                  NULL, NULL);
721  f = XjVaCreateJet("form", formJetClass, win, NULL, NULL);
722
723  /*
724   * Button
725   */
726  w = XjVaCreateJet("hide", windowJetClass, f, NULL, NULL);
727  b = XjVaCreateJet("hideButton", buttonJetClass, w, NULL, NULL);
728  (void) XjVaCreateJet("hideLabel", labelJetClass, b, NULL, NULL);
729
730  /*
731   * Arrow buttons
732   */
733  w = XjVaCreateJet("scrollup", windowJetClass, f, NULL, NULL);
734  b = XjVaCreateJet("scrollupButton", buttonJetClass, w, NULL, NULL);
735  (void) XjVaCreateJet("scrollupArrow", arrowJetClass, b, NULL, NULL);
736
737  w = XjVaCreateJet("scrolldown", windowJetClass, f, NULL, NULL);
738  b = XjVaCreateJet("scrolldownButton", buttonJetClass, w, NULL, NULL);
739  (void) XjVaCreateJet("scrolldownArrow", arrowJetClass, b, NULL, NULL);
740
741  /*
742   * Label
743   */
744  (void) XjVaCreateJet("title", labelJetClass, f, NULL, NULL);
745
746  /*
747   * Scrollbar
748   */
749  w = XjVaCreateJet("scrollBarWindow", windowJetClass, f, NULL, NULL);
750  sj = (ScrollBarJet) XjVaCreateJet("scrollBar",
751                                    scrollBarJetClass, w, NULL, NULL);
752
753  /*
754   * TextDisplay
755   */
756  w = XjVaCreateJet("textDisplayWindow", windowJetClass, f, NULL, NULL);
757  tj = (TextDisplayJet) XjVaCreateJet("textDisplay",
758                                      textDisplayJetClass, w, NULL, NULL);
759
760
761  XjRealizeJet((Jet) XjParent(f));
762
763
764  if (! stat(parms.file, &buf)) /* If there was an error stat'ing the */
765    size = (int)buf.st_size;    /* file, we will find out soon enough */
766                                /* when we call loadFile below.  No need */
767                                /* to display an error msg here. */
768
769  size = (size > BUFSIZE) ? size : BUFSIZE;
770  text = XjMalloc(size);
771  text[0] = '\0';
772  length = 0;
773  length = loadFile(parms.file, text, size);
774
775  if (parms.input && *parms.input)
776    {
777      auxinput = open(parms.input, O_RDONLY, 0);
778      if (auxinput == -1)
779        {
780#define CANT_OPEN "console: can't open input\n"
781          appendToBuffer(CANT_OPEN, sizeof(CANT_OPEN)-1);
782        }
783    }
784  SetText(tj, text);
785
786  cl = CountLines(tj);
787  vl = VisibleLines(tj);
788
789  if (parms.autoscroll)
790    {
791      val = MAX(0, cl - vl);
792
793      SetScrollBar(sj, 0, MAX(cl - 1, 0), vl, val);
794      SetLine(tj, val);
795    }
796
797  if (parms.nostdin == False)
798    XjReadCallback((XjCallbackProc)input, zero, (caddr_t) &zero);
799
800  if (auxinput != -1)
801    XjReadCallback((XjCallbackProc)input, auxinput, (caddr_t) &auxinput);
802
803  if (parms.inputfd != 0)
804    XjReadCallback((XjCallbackProc)input, parms.inputfd,
805                   (caddr_t) &parms.inputfd);
806
807  XjSetSignalChecker(checkSignals);
808
809  XjEventLoop(root);
810}
Note: See TracBrowser for help on using the repository browser.