Newsgroups: fj.comp.texhax
Path: galaxy.trc.rwcp.or.jp!coconuts.jaist!wnoc-tyo-news!wnoc-sfc-news!wnoc-kyo-news!aist-nara!odins-suita!icluna!uchiyama
From: uchiyama@bacchus.in.kobe-u.ac.jp (Takanori Uchiyama)
Subject: Re: a patch of xdvi PL18 for ASCII Nihongo TeX and VFlib 2.x
Sender: news@icluna.kobe-u.ac.jp (news-admin)
Message-ID: <UCHIYAMA.95Mar13185933@in5at3.bacchus.in.kobe-u.ac.jp>
In-Reply-To: miyu@shiratori.riec.tohoku.ac.jp's message of 13 Mar 1995 05:46:33 GMT
Date: Mon, 13 Mar 1995 09:59:33 GMT
Distribution: fj
References: <S31514.95Mar1175527@ecc-1000.ecc.u-tokyo.ac.jp>
	<UCHIYAMA.95Mar10222526@in5at3.bacchus.in.kobe-u.ac.jp>
	<MIYU.95Mar13144633@pigeon.shiratori.riec.tohoku.ac.jp>
Organization: Akazawa Lab. Dept. Comp. & Systems, Fac. Eng., Kobe Univ., Kobe,
	JAPAN
Lines: 3813
Xref: galaxy.trc.rwcp.or.jp fj.comp.texhax:6049
X-originally-archived-at: http://galaxy.rwcp.or.jp/text/cgi-bin/newsarticle2?ng=fj.comp.texhax&nb=6049&hd=a
X-reformat-date: Mon, 18 Oct 2004 15:18:22 +0900
X-reformat-comment: Tabs were expanded into 4 column tabstops by the Galaxy's archiver. See http://katsu.watanabe.name/ancientfj/galaxy-format.html for more info.

$BFb;3!w?@8MBg$G$9(B.

$B@hF|(B, $B%]%9%H$7$?(B epsbox.sty $B$r;H$C$F:9$79~$s$@(B EPS $B$rI=<($9$k%Q%C%A$G(B
$B$9$,(B, $BEj9FA0$KM>7W$J$3$H$r$7$?$P$+$j$K(B, $B%(%s%P%0$7$F$7$F$7$^$$$^$7$?(B.
dvi2ps-j $B$K4^$^$l$F$$$k(B epsf.sty $B$r;H$C$F:9$79~$s$@(B EPS $B$rI=<($9$k%Q%C(B
$B%A$rIU2C$7$?$N$G(B, $BM_D%$C$F(B vi $B%i%$%/$J%-!<%P%$%s%I(B VI_KEY, DVI $B%U%!%$(B
$B%k$r%a%K%e!<7A<0$GA*Br$9$k(B SELFILE $B$N%Q%C%A$bIU2C$7$^$7$?(B. 

$B%*%j%8%J%k$N(B xdvi PL18 $B$N%=!<%9$K(B, $B2,@n$5$s$N%Q%C%A$r$"$F$?8e$K(B, $B0J2<(B
$B$N%Q%C%A$r$"$F$F$/$@$5$$(B. $B@hF|$N(B epsbox.sty $B$N$?$a$N%Q%C%A$O(B, $B$"$F$J$$(B
$B$G$/$@$5$$(B.

Imakefile $B$K(B VI_KEY, SELFILE $B$r;XDj$7$F$$$^$9(B. $BE,59$O$:$J$j;D$9$J$j$7(B
$B$F2<$5$$(B. 

$B$=$l$+$i(B, PL18 $B$+$i$O(B, $B%j!<%=%9$rFI$`$h$&$K$J$C$F$$$^$9(B. 
$B;d$O(B
/usr/X11/lib/X11/app-defaults/XDvi $B$K(B
XDvi.shrinkFactor: 5
XDvi.postscript: off
$B$J$I$N$h$&$K5-=R$7$F$*$-$^$7$?(B. $BA0<T$O(B, shrink size $B$r(B 5 $B$K(B(400dpi $B$N(B
$B%U%)%s%H$r;H$C$F$$$k>l9g$K(B, 1280x1024 $B$G(B A4 $B$,2hLL$K$*$5$^$k(B), $B8e<T$O(B,
$B5/F0;~$K$O(B EPS $B$d(B PS $B$NI=<($r9T$J$o$J$$;XDj$G$9(B.

$B$=$l$+$i(B, X server $B$,(B 16bpp $B$N;~$K$H$s$G$b$J$$NL$N%a%b%j$rMW5a$7$?7o$O(B,
$B$J$<$+H/@8$7$J$/$J$C$F$7$^$$$^$7$?(B. $B$-$C$H;d$,$\$1$F$$$?$N$G$7$g$&(B.

In article <MIYU.95Mar13144633@pigeon.shiratori.riec.tohoku.ac.jp> miyu@shiratori.riec.tohoku.ac.jp (Shigeki "miyu" SUGIURA) writes:

   miyu17beta.6 $B$O>/$J$/$H$b%P%0$"$j$G$9!#B?J,$=$l$,860x$G$7$g$&!#(B
   miyu17beta.pre7 $BMQ$N%Q%C%A$,=P$F$$$^$9!#(B

$B$b$&0lEY(B beta.pre7 $B$G;n$7$F$_$^$9(B. $B$I$&$b$"$j$,$H$&$4$6$$$^$9(B.

---cut here---cut here---cut here---
#!/bin/sh
# shar:Shell Archiver  (v1.22)
#
#Run the following text with /bin/sh to create:
#  xdvipl18_epsbox+elepsf+selfile+vikey.patch
#  Dir.c
#  Draw.c
#  Path.c
#  SFinternal.h
#  SelFile.c
#  xstat.h
#
sed 's/^X//' << 'SHAR_EOF' > xdvipl18_epsbox+elepsf+selfile+vikey.patch &&
Xdiff -c xdvi18_old/Imakefile xdvi18/Imakefile
X*** xdvi18_old/ImakefileSat Mar 11 22:33:45 1995
X--- xdvi18/ImakefileMon Mar 13 17:25:04 1995
X***************
X*** 2,7 ****
X--- 2,9 ----
X   * Imakefile for dvi previewer.
X   */
X  
X+ #define Use_MAKEPK
X+ #define Use_SELFILE
X  #defineUse_KANJI
X  #undefUse_ASCIIDNP
X  #defineUse_ZEIT
X***************
X*** 12,27 ****
X  
X  XCOMM The following five lines are the crucial ones.
X  TEXLIB=/usr/local/lib/tex
X! TEXFONTS=$(TEXLIB)/fonts          /* where jfm files are located */
X! PKFONTS=$(TEXLIB)/300pk
X  
X  #ifdefUse_ZEIT
X! VFLIB=/usr/local/lib/VFlib-2.16.2/VFlib.a
X  #endif
X  
X! DEFAULT_FONT_PATH=.:/usr/local/lib/nttjtex/pk:$(PKFONTS)/cmfonts:$(TEXLIB)/amspk:$(TEXFONTS)
X  DEFAULT_VF_PATH=/usr/local/tex/fonts/vf
X! DEFAULT_FONT_SIZES=$(SIZES300)
X  
X  #ifdefUse_KANJI
X  #ifdefUse_ASCIIDNP
X--- 14,38 ----
X  
X  XCOMM The following five lines are the crucial ones.
X  TEXLIB=/usr/local/lib/tex
X! TEXFONTS=$(TEXLIB)/fonts/tfm          /* where jfm files are located */
X! PKFONTS=$(TEXLIB)/fonts/pk400
X  
X  #ifdefUse_ZEIT
X! VFLIB=/usr/local/lib/VFlib.a
X  #endif
X  
X! DEFAULT_FONT_PATH=.:$(PKFONTS):$(TEXFONTS)
X  DEFAULT_VF_PATH=/usr/local/tex/fonts/vf
X! DEFAULT_FONT_SIZES=$(SIZES400)
X! 
X! #ifdefUse_MAKEPK
X! MAKEPK_BINDIR=$(LOCALBIN)
X! MAKEPK_DESTDIR=$(TEXFONTS)/pk400
X! MAKEPK_DEFS=-DMAKEPK \
X!             -DMAKEPKCMD=\"$(MAKEPK_BINDIR)/MakeTeXPK\"
X! #else
X! MAKEPK_DEFS=
X! #endif/* Use_MAKEPK */
X  
X  #ifdefUse_KANJI
X  #ifdefUse_ASCIIDNP
X***************
X*** 35,41 ****
X    
X  #ifdefUse_ZEIT
X  DEFAULT_FONTCONFDIR=$(DEFAULT_VF_PATH)
X! DEFAULT_FONTCONF=$(TEXLIB)/vfonts/FontConf
X  #ifdefUse_NTTZEIT
X  ZEIT_DEFS=-DUSE_ZEIT -DNTTZEIT -DDEFAULT_FONTCONF=\"$(DEFAULT_FONTCONF)\"
X  #else
X--- 46,52 ----
X    
X  #ifdefUse_ZEIT
X  DEFAULT_FONTCONFDIR=$(DEFAULT_VF_PATH)
X! DEFAULT_FONTCONF=$(TEXLIB)/vfontdesc
X  #ifdefUse_NTTZEIT
X  ZEIT_DEFS=-DUSE_ZEIT -DNTTZEIT -DDEFAULT_FONTCONF=\"$(DEFAULT_FONTCONF)\"
X  #else
X***************
X*** 55,60 ****
X--- 66,79 ----
X  LINTLIBS_TOOL=$(VARLINT) $(LINTXAW) $(LINTXMU) $(LINTXTOOL) \
X    $(LINTEXTENSIONLIB) $(LINTXLIB) -lm
X  
X+ #ifdef  Use_SELFILE
X+ #define SELFILE_SRCS    Dir.c Draw.c Path.c SelFile.c
X+ #define SELFILE_OBJS    Dir.o Draw.o Path.o SelFile.o
X+ #else
X+ #define SELFILE_SRCS
X+ #define SELFILE_OBJS
X+ #endif  /* Use_SELFILE */
X+ 
X  LOCAL_LIBRARIES_NOT=$(VARLIBS) $(XLIB)
X  DEPLIBS_NOT=$(VARDEPLIBS) $(DEPXLIB)
X  LINTLIBS_NOT=$(VARLINT) $(LINTXLIB) -lm
X***************
X*** 63,71 ****
X  SYS_LIBRARIES=$(MATHLIB)
X  
X  OSDEFS=
X! OPTIONDEFS=-DUSE_PK -DUSE_GF -DA4 -DBUTTONS -DGREY -DPS_GS \
X             $(KANJI_DEFS) $(ZEIT_DEFS)
X! DEFS=$(OSDEFS) $(OPTIONDEFS)
X  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
X    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
X    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
X--- 82,91 ----
X  SYS_LIBRARIES=$(MATHLIB)
X  
X  OSDEFS=
X! OPTIONDEFS=-DUSE_PK -DUSE_GF -DA4 -DBUTTONS -DGREY -DPS_GS -DTEXET -DMAKEPK \
X             $(KANJI_DEFS) $(ZEIT_DEFS)
X! DEFS=-DBDPI=400 -UMSBITFIRST -UBMLONG -UBMSHORT -DVI_KEY \
X!      -DSELFILE $(OSDEFS) $(OPTIONDEFS)
X  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
X    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
X    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
X***************
X*** 93,101 ****
X  include Makefile.cfg
X  
X  SRCS=xdvi.c events.c dvi_init.c dvi_draw.c special.c font_open.c vf.c util.c \
X!   $(VARSRCS)
X  OBJS=xdvi.o events.o dvi_init.o dvi_draw.o special.o font_open.o vf.o util.o \
X!   $(VAROBJS)
X  
X  ComplexProgramTarget(xdvi)
X  
X--- 113,121 ----
X  include Makefile.cfg
X  
X  SRCS=xdvi.c events.c dvi_init.c dvi_draw.c special.c font_open.c vf.c util.c \
X!   $(VARSRCS) SELFILE_SRCS
X  OBJS=xdvi.o events.o dvi_init.o dvi_draw.o special.o font_open.o vf.o util.o \
X!   $(VAROBJS) SELFILE_OBJS
X  
X  ComplexProgramTarget(xdvi)
X  
Xdiff -c xdvi18_old/dvi_init.c xdvi18/dvi_init.c
X*** xdvi18_old/dvi_init.cSat Mar 11 22:33:45 1995
X--- xdvi18/dvi_init.cMon Mar 13 17:48:22 1995
X***************
X*** 768,773 ****
X--- 768,776 ----
X  check_dvi_file()
X  {
X  struct font *fontp;
X+ #ifdefSELFILE
X+ externFILE *select_filename();
X+ #endif/* SELFILE */
X  
X  if (dvi_file == NULL || fstat(fileno(dvi_file), &fstatbuf) != 0
X      || fstatbuf.st_mtime != dvi_time) {
X***************
X*** 781,787 ****
X  tn_head = NULL;
X  for (fontp = font_head; fontp != NULL; fontp = fontp->next)
X      fontp->flags &= ~FONT_IN_USE;
X! if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL
X  || !init_dvi_file())
X      dvi_oops("Cannot reopen dvi file.");
X  reconfig();
X--- 784,796 ----
X  tn_head = NULL;
X  for (fontp = font_head; fontp != NULL; fontp = fontp->next)
X      fontp->flags &= ~FONT_IN_USE;
X! #ifdefSELFILE
X! if (dvi_time > fstatbuf.st_mtime) /* choose a new file time */
X!     dvi_file = select_filename(True, True);
X! else
X! #endif/* SELFILE */
X!     dvi_file = fopen(dvi_name, OPEN_MODE);
X! if (dvi_file == NULL
X  || !init_dvi_file())
X      dvi_oops("Cannot reopen dvi file.");
X  reconfig();
Xdiff -c xdvi18_old/events.c xdvi18/events.c
X*** xdvi18_old/events.cTue May 17 17:41:55 1994
X--- xdvi18/events.cMon Mar 13 17:09:52 1995
X***************
X*** 175,188 ****
X  inty_pos;
X  }
X  command_table[] = {
X! {"Quit","quit",'q',50},
X  {"Shrink1","sh1",1 << 8 | 's',150},
X  {"Shrink2","sh2",2 << 8 | 's',200},
X  {"Shrink3","sh3",3 << 8 | 's',250},
X  {"Shrink4","sh4",4 << 8 | 's',300},
X! {"Page-10","prev10",10 << 8 | 'p',400},
X! {"Page-5","prev5",5 << 8 | 'p',450},
X! {"Prev","prev",'p',500},
X  {"Next","next",'n',600},
X  {"Page+5","next5",5 << 8 | 'n',650},
X  {"Page+10","next10",10 << 8 | 'n',700},
X--- 175,192 ----
X  inty_pos;
X  }
X  command_table[] = {
X! {"Quit","quit",'q',20},
X! #ifdefSELFILE
X! {"File","file",'F', 80},
X! #endif/* SELFILE */
X  {"Shrink1","sh1",1 << 8 | 's',150},
X  {"Shrink2","sh2",2 << 8 | 's',200},
X  {"Shrink3","sh3",3 << 8 | 's',250},
X  {"Shrink4","sh4",4 << 8 | 's',300},
X! {"Shrink5","sh5",5 << 8 | 's',350},
X! {"Page-10","prev10",10 << 8 | 'p',425},
X! {"Page-5","prev5",5 << 8 | 'p',475},
X! {"Prev","prev",'p',525},
X  {"Next","next",'n',600},
X  {"Page+5","next5",5 << 8 | 'n',650},
X  {"Page+10","next10",10 << 8 | 'n',700},
X***************
X*** 1017,1023 ****
X--- 1021,1031 ----
X      case 'P':/* declare current page */
X  pageno_correct = arg0 * number0 - current_page;
X  return;
X+ #ifdef  VI_KEY
X+             case 'K':           /* toggle keep-position flag */
X+ #else   /* VI_KEY */
X      case 'k':/* toggle keep-position flag */
X+ #endif  /* VI_KEY */
X  resource.keep_flag = (arg0 ? number0 : !resource.keep_flag);
X  return;
X      case '\f':
X***************
X*** 1027,1048 ****
X--- 1035,1076 ----
X  home(True);
X  return;
X  #ifdefTOOLKIT
X+ #ifdef  VI_KEY
X+             case 'h':
X+             case '\002':        /* control-B */
X+ #else   /* VI_KEY */
X      case 'l':
X+ #endif  /* VI_KEY */
X  if (!x_bar) goto bad;
X  XtCallCallbacks(x_bar, XtNscrollProc,
X      (XtPointer) (-2 * (int) clip_w / 3));
X  return;
X+ #ifdef  VI_KEY
X+             case 'l':
X+             case '\006':        /* control-F */
X+ #else   /* VI_KEY */
X      case 'r':
X+ #endif  /* VI_KEY */
X  if (!x_bar) goto bad;
X  XtCallCallbacks(x_bar, XtNscrollProc,
X      (XtPointer) (2 * (int) clip_w / 3));
X  return;
X+ #ifdef  VI_KEY
X+             case 'k':
X+             case '\020':        /* control-P */
X+ #else   /* VI_KEY */
X      case 'u':
X+ #endif  /* VI_KEY */
X  if (!y_bar) goto bad;
X  XtCallCallbacks(y_bar, XtNscrollProc,
X      (XtPointer) (-2 * (int) clip_h / 3));
X  return;
X+ #ifdef  VI_KEY
X+             case 'j':
X+             case '\016':        /* control-N */
X+ #else   /* VI_KEY */
X      case 'd':
X+ #endif  /* VI_KEY */
X  if (!y_bar) goto bad;
X  XtCallCallbacks(y_bar, XtNscrollProc,
X      (XtPointer) (2 * (int) clip_h / 3));
X***************
X*** 1078,1096 ****
X--- 1106,1144 ----
X  return;
X  #endif/* BUTTONS */
X  #else/* !TOOLKIT */
X+ #ifdef  VI_KEY
X+             case 'h':
X+             case '\002':        /* control-B */
X+ #else   /* VI_KEY */
X      case 'l':
X+ #endif  /* VI_KEY */
X  if (mane.base_x <= 0) goto bad;
X  scrollmane(mane.base_x - 2 * (int) clip_w / 3, mane.base_y);
X  return;
X+ #ifdef  VI_KEY
X+             case 'l':
X+             case '\006':        /* control-F */
X+ #else   /* VI_KEY */
X      case 'r':
X+ #endif  /* VI_KEY */
X  if (mane.base_x >= page_w - clip_w) goto bad;
X  scrollmane(mane.base_x + 2 * (int) clip_w / 3, mane.base_y);
X  return;
X+ #ifdef  VI_KEY
X+             case 'k':
X+             case '\020':        /* control-P */
X+ #else   /* VI_KEY */
X      case 'u':
X+ #endif  /* VI_KEY */
X  if (mane.base_y <= 0) goto bad;
X  scrollmane(mane.base_x, mane.base_y - 2 * (int) clip_h / 3);
X  return;
X+ #ifdef  VI_KEY
X+             case 'j':
X+             case '\016':        /* control-N */
X+ #else   /* VI_KEY */
X      case 'd':
X+ #endif  /* VI_KEY */
X  if (mane.base_y >= page_h - clip_h) goto bad;
X  scrollmane(mane.base_x, mane.base_y + 2 * (int) clip_h / 3);
X  return;
X***************
X*** 1110,1120 ****
X--- 1158,1170 ----
X  return;
X  #endif/* TOOLKIT */
X  
X+ #ifndef VI_KEY
X      case '\020':/* Control P */
X  Printf("Unit = %d, bitord = %d, byteord = %d\n",
X      BitmapUnit(DISP), BitmapBitOrder(DISP),
X      ImageByteOrder(DISP));
X  return;
X+ #endif  /* !VI_KEY */
X      case 's':
X  if (!arg0) {
X      int temp;
X***************
X*** 1144,1149 ****
X--- 1194,1204 ----
X  reset_fonts();
X  if (mane.shrinkfactor == 1) return;
X  break;
X+ #ifdefSELFILE
X+     case 'F':
X+ ++dvi_time;
X+ break;
X+ #endif/* SELFILE */
X  #ifdefGREY
X      case 'G':
X  use_grey = (arg0 ? number0 : !use_grey);
X***************
X*** 1153,1158 ****
X--- 1208,1214 ----
X  #endif
X  
X  #ifPS
X+             case '\007':        /* CTRL-G */
X      case 'v':
X  if (!arg0 || resource._postscript != !number0) {
X      resource._postscript = !resource._postscript;
X***************
X*** 1183,1188 ****
X--- 1239,1295 ----
X  bad:  XBell(DISP, 10);
X  }
X  
X+ /* Allow the user to choose a new dvi file, by popping up a dialog box
X+    which allows the graphical selection of the correct filename,
X+    maybe we should only allow files ending in .dvi to be selected???  JSP
X+ */
X+ #ifdefSELFILE
X+ FILE *
X+ select_filename(open, move_home)
X+ int open, move_home;
X+ {
X+ externFILE*XsraSelFile();
X+ FILE*dummy_file = (FILE *) NULL;
X+ static char*dummy_name;
X+ #ifdefTOOLKIT
X+ static Argtemp_args[] = {
X+     {XtNtitle,(XtArgVal) 0},
X+     {XtNinput,(XtArgVal) True},
X+ };
X+ #endif
X+ 
X+ dummy_file = XsraSelFile(top_level, "Select a dvi file: ",
X+  "Ok", "Cancel",
X+  "Can't open file: ", NULL,
X+  OPEN_MODE, NULL, &dummy_name);
X+ if (dummy_file != NULL) {
X+     /* we may not want the file they returned... */
X+     if (!open) {
X+ Fclose(dummy_file);
X+ dummy_file = (FILE *) NULL;
X+     }
X+     /* the name is what we really want, so use it  JSP */
X+     dvi_name = dummy_name;
X+     current_page = 0;/* go to start of new dvi file */
X+     if (move_home)
X+ home(False);/* Move to home position on new first page */
X+ #ifdefTOOLKIT
X+ /* Attempt to set the name correctly (only try for toolkit version) */
X+     title_name = xmalloc((unsigned) sizeof("Xdvi: ") + strlen(dvi_name),
X+  "xdvi title");
X+     Sprintf(title_name, "Xdvi: %s", dvi_name);
X+     temp_args[0].value = (XtArgVal) title_name;
X+     XtSetValues(top_level, temp_args, XtNumber(temp_args));
X+ #endif
X+ } else {
X+     /* User cancelled, so open old file */
X+     if (open)
X+ dummy_file = fopen(dvi_name, OPEN_MODE);
X+ }
X+ 
X+ return dummy_file;
X+ }
X+ #endif/* SELFILE */
X  
X  #defineTRSIZE100
X  
XCommon subdirectories: xdvi18_old/gsftopk and xdvi18/gsftopk
Xdiff -c xdvi18_old/special.c xdvi18/special.c
X*** xdvi18_old/special.cMon May 16 11:18:01 1994
X--- xdvi18/special.cMon Mar 13 18:08:13 1995
X***************
X*** 676,681 ****
X--- 676,685 ----
X  #defineKEY_URYkeyval[3]
X  #defineKEY_RWIkeyval[4]
X  #defineKEY_RHIkeyval[5]
X+ #defineKEY_HSZkeyval[6]
X+ #defineKEY_VSZkeyval[7]
X+ #defineKEY_HSCkeyval[10]
X+ #defineKEY_VSCkeyval[11]
X  
X  #defineNKEYS(sizeof(keytab)/sizeof(*keytab))
X  #defineN_ARGLESS_KEYS 1
X***************
X*** 691,697 ****
X  char*p;
X  char*q;
X  intflags= 0;
X! doublekeyval[6];
X  
X  if (memcmp(cp, "ile=", 4) != 0) {
X      if (!hush_spec_now)
X--- 695,701 ----
X  char*p;
X  char*q;
X  intflags= 0;
X! doublekeyval[12];
X  
X  if (memcmp(cp, "ile=", 4) != 0) {
X      if (!hush_spec_now)
X***************
X*** 780,785 ****
X--- 784,1110 ----
X  }
X  
X  
X+ /***************************************************************
X+   Following two functions, dirname() and get_boudig_box()
X+   come from ps.c in miyu-patch for xdvi PL17. 
X+ ***************************************************************/
X+ 
X+ static  char *
X+ dirname(f1, f2)
X+         char    *f1;
X+         char    *f2;
X+ {
X+         char    *p1, *p2, *q1;
X+         static char     buf[BUFSIZ];
X+ 
X+ #ifndef VMS
X+         if (*f2 == '/')
X+                 return f2;
X+ #endif  /* !VMS */
X+ 
X+         for (p1 = p2 = f1, q1 = buf; *p1; p1++, q1++) {
X+ #ifndef VMS
X+             if (*p1 == '/')
X+ #else
X+             if (*p1 == ':')
X+ #endif  /* !VMS */
X+                 p2 = p1 + 1;
X+             *q1 = *p1;
X+         }
X+         Strcpy(buf + (p2 - f1), f2);
X+ 
X+         return buf;
X+ }
X+ 
X+ int
X+ get_bounding_box(psfile, llx, lly, urx, ury)
X+         char    *psfile;
X+         double   *llx;
X+         double   *lly;
X+         double   *urx;
X+         double   *ury;
X+ {
X+         FILE    *fptr;
X+         char    buf[BUFSIZ];
X+ 
X+         if ((fptr = xfopen(psfile, "r")) == NULL) {
X+             perror(psfile);
X+             return -1;
X+         }
X+ 
X+         for (;;) {
X+             if (fgets(buf, BUFSIZ, fptr) == NULL) {
X+                 Fprintf(stderr, "%s:unexpected EOF.\n", psfile);
X+                 Fclose(fptr);
X+                 return -1;
X+             }
X+             if (strncmp(buf, "%%BoundingBox:", 14) == 0) {
X+                 if (sscanf(buf + 14, "%lf %lf %lf %lf", llx, lly, urx, ury) < 4) {
X+                     Fprintf(stderr, "\\special: ERROR.\n");
X+                     Fclose(fptr);
X+                     return -1;
X+                 }
X+                 break;
X+             }
X+         }
X+ 
X+         Fclose(fptr);
X+ 
X+         return 0;
X+ }
X+ 
X+ 
X+ /***************************************************************
X+   The originai eps_special() is merged with psSpecial() in ps.c  
X+   (miyu-patch for xdvi PL17). 
X+ ***************************************************************/
X+ staticvoid
X+ epsbox_special(cp)
X+ char*cp;
X+ {
X+ char*filename;
X+ staticchar*buffer = NULL;
X+ unsigned intlen;
X+ char*p;
X+ char*q;
X+ intflags= 0;
X+ doublekeyval[12];
X+ 
X+         float   hsize = 0.0, vsize = 0.0;
X+         float   hscale = 0.0, vscale = 0.0;
X+ char *ptr;
X+ 
X+ if (memcmp(cp, "tscriptbox{", 11) != 0) {
X+     if (!hush_spec_now)
X+ Fprintf(stderr, "epsbox special pos%s is unknown\n", cp);
X+     return;
X+ }
X+ 
X+ p = cp + 11;
X+ if ((ptr = strtok(p, "{}")) == NULL) {
X+   Fprintf(stderr, "\\special: ERROR.\n");
X+   return;
X+ }
X+ hsize = atof(ptr);
X+ if ((ptr = strtok(NULL, "{}")) == NULL) {
X+   Fprintf(stderr, "\\special: ERROR.\n");
X+   return;
X+ }
X+ vsize = atof(ptr);
X+ if ((ptr = strtok(NULL, "{}")) == NULL) {
X+   Fprintf(stderr, "\\special: ERROR.\n");
X+   return;
X+ }
X+ filename = dirname(dvi_name, ptr);
X+ 
X+ if (get_bounding_box(filename,
X+      &KEY_LLX, &KEY_LLY,
X+      &KEY_URX, &KEY_URY))
X+   return;
X+ 
X+ if (hsize != 0.0)
X+   hscale = hsize / (KEY_URX - KEY_LLX);
X+ if (vsize != 0.0)
X+   vscale = vsize / (KEY_URY - KEY_LLY);
X+ 
X+ if (hscale == 0.0 && vscale == 0.0)
X+   hscale = vscale = 1.0;
X+ else if (hscale == 0.0)
X+   hscale = vscale;
X+ else if (vscale == 0.0)
X+   vscale = hscale;
X+ 
X+ KEY_RWI = hsize;
X+ KEY_RHI = vsize;
X+ 
X+ if (buffer == NULL)
X+     buffer = xmalloc(BUFSIZ, "epsf buffer");
X+ 
X+ Strcpy(buffer, "@beginspecial");
X+ q = buffer + strlen(buffer);
X+ sprintf(q, " /@scaleunit 1 def");
X+ q += strlen(q);
X+ /*sprintf(q, " %lf @llx", KEY_LLX);
X+ q += strlen(q);
X+ sprintf(q, " %lf @lly", KEY_LLY);
X+ q += strlen(q);
X+ sprintf(q, " %lf @urx", KEY_URX);
X+ q += strlen(q);
X+ sprintf(q, " %lf @ury", KEY_URY);
X+ q += strlen(q);
X+ sprintf(q, " %lf @rwi", KEY_RWI);
X+ q += strlen(q);
X+ sprintf(q, " %lf @rhi", KEY_RWI);
X+ q += strlen(q);
X+ sprintf(q, " %lf @hsize", hsize);
X+ q += strlen(q);
X+ sprintf(q, " %lf @vsize", vsize);
X+ q += strlen(q);
X+ */sprintf(q, " %lf @hoffset", -KEY_LLX * hscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @voffset", -KEY_LLY * vscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @hscale", hscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @vscale", vscale);
X+ q += strlen(q);
X+ Strcpy(q, " @setspecial\n");
X+ 
X+ 
X+ bbox_valid = True;
X+ bbox_width =  KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY - KEY_LLY)
X+   * dimconv / shrink_factor + 0.5;
X+ bbox_voffset = bbox_height = KEY_RWI * (KEY_URY - KEY_LLY) / (KEY_URX - KEY_LLX)
X+   * dimconv / shrink_factor + 0.5;
X+ 
X+ if (currwin.win == mane.win) {
X+ #ifPS
X+     psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
X+ buffer);
X+     /* talk directly with the DPSHandler here */
X+     psp.drawfile(filename);
X+     psp.drawend(" @endspecial");
X+ #else
X+     draw_bbox();
X+ #endif
X+ }
X+ bbox_valid = False;
X+ }
X+ 
X+ staticvoid
X+ elepsf_special(cp)
X+ char*cp;
X+ {
X+ char*filename;
X+ staticchar*buffer;
X+ staticunsigned intbuflen= 0;
X+ unsigned intlen;
X+ char*p;
X+ char*q;
X+ intflags= 0;
X+ doublekeyval[12] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
X+                               0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
X+         float   hsize = 0.0, vsize = 0.0;
X+         float   hscale = 0.0, vscale = 0.0;
X+ 
X+ if (memcmp(cp, "file=", 5) != 0) {
X+     if (!hush_spec_now)
X+ Fprintf(stderr, "epsf special PSf%s is unknown\n", cp);
X+     return;
X+ }
X+ 
X+ p = cp + 5;
X+ filename = p;
X+ if (*p == '\'' || *p == '"') {
X+     do ++p;
X+     while (*p != '\0' && *p != *filename);
X+     ++filename;
X+ }
X+ else
X+     while (*p != '\0' && *p != ' ' && *p != '\t') ++p;
X+ if (*p != '\0') *p++ = '\0';
X+ while (*p == ' ' || *p == '\t') ++p;
X+ 
X+ filename = dirname(dvi_name, filename);
X+ 
X+ if (get_bounding_box(filename,
X+      &KEY_LLX, &KEY_LLY,
X+      &KEY_URX, &KEY_URY))
X+   return;
X+ 
X+ len = strlen(p) + NKEYS + 512;
X+ if (buflen < len) {
X+     if (buflen != 0) free(buffer);
X+     buflen = len;
X+     buffer = xmalloc(buflen, "epsf buffer");
X+ }
X+ Strcpy(buffer, "@beginspecial");
X+ q = buffer + strlen(buffer);
X+ sprintf(q, " /@scaleunit 1 def");
X+ q += strlen(q);
X+ while (*p != '\0') {
X+     char *p1 = p;
X+     int keyno;
X+ 
X+     while (*p1 != '=' && !isspace(*p1) && *p1 != '\0') ++p1;
X+     for (keyno = 0;; ++keyno) {
X+ if (keyno >= NKEYS) {
X+     if (!hush_spec_now)
X+ Fprintf(stderr,
X+     "unknown keyword (%*s) in \\special will be ignored\n",
X+     (int) (p1 - p), p);
X+     break;
X+ }
X+ if (memcmp(p, keytab[keyno], p1 - p) == 0) {
X+     if (keyno >= N_ARGLESS_KEYS) {
X+ if (*p1 == '=') ++p1;
X+ if (keyno < N_ARGLESS_KEYS + 12) {
X+     keyval[keyno - N_ARGLESS_KEYS] = atof(p1);
X+     flags |= (1 << (keyno - N_ARGLESS_KEYS));
X+ }
X+ *q++ = ' ';
X+ while (!isspace(*p1) && *p1 != '\0') p1++;
X+     }
X+     break;
X+ }
X+     }
X+     p = p1;
X+     while (!isspace(*p) && *p != '\0') ++p;
X+     while (isspace(*p)) ++p;
X+ }
X+ 
X+ hsize = KEY_HSZ;
X+ vsize = KEY_VSZ;
X+ hscale = KEY_HSC;
X+ vscale = KEY_VSC;
X+ if (hsize != 0.0)
X+   hscale = hsize / (KEY_URX - KEY_LLX);
X+ if (vsize != 0.0)
X+   vscale = vsize / (KEY_URY - KEY_LLY);
X+ 
X+ KEY_RWI = KEY_URX - KEY_LLX;
X+ KEY_RHI = KEY_URY - KEY_LLY;
X+ 
X+ if (hscale == 0.0 && vscale == 0.0)
X+   hscale = vscale = 1.0;
X+ else if (hscale == 0.0)
X+   hscale = vscale;
X+ else if (vscale == 0.0)
X+   vscale = hscale;
X+ 
X+ KEY_RHI *= vscale;
X+ KEY_RWI *= hscale;
X+ 
X+ sprintf(q, " %lf @hoffset", -KEY_LLX * hscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @voffset", -KEY_URY * vscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @hscale", hscale);
X+ q += strlen(q);
X+ sprintf(q, " %lf @vscale", vscale);
X+ q += strlen(q);
X+ Strcpy(q, " @setspecial\n");
X+ 
X+ bbox_valid = True;
X+ bbox_width = KEY_RWI * dimconv / shrink_factor + 0.5;
X+ bbox_voffset = 0.0; 
X+         bbox_height = KEY_RHI * dimconv / shrink_factor + 0.5;
X+ 
X+ if (currwin.win == mane.win) {
X+ #ifPS
X+     psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
X+ buffer);
X+     /* talk directly with the DPSHandler here */
X+     psp.drawfile(filename);
X+     psp.drawend(" @endspecial");
X+ #else
X+     draw_bbox();
X+ #endif
X+ }
X+ bbox_valid = False;
X+ }
X+ 
X+ 
X  staticvoid
X  quote_special(cp)
X  char*cp;
X***************
X*** 856,861 ****
X--- 1181,1188 ----
X  else if (strcmp(command, "ps:") == 0) psfig_special(cp);
X  else if (strcmp(command, "PSf") == 0) epsf_special(cp);
X  else if (strcmp(command, "psf") == 0) epsf_special(cp);
X+ else if (strcmp(command, "eps") == 0) elepsf_special(cp);
X+ else if (strcmp(command, "pos") == 0) epsbox_special(cp);
X  else if (*orig_cp == '"') quote_special(orig_cp + 1);
X  else if (!hush_spec_now)
X      Fprintf(stderr, "%s:  special \"%s\" not implemented\n", prog,
Xdiff -c xdvi18_old/xdvi.c xdvi18/xdvi.c
X*** xdvi18_old/xdvi.cSat Mar 11 22:33:46 1995
X--- xdvi18/xdvi.cMon Mar 13 17:09:48 1995
X***************
X*** 63,68 ****
X--- 63,69 ----
X   *PS_DPSuse display postscript to render pictures/bounding boxes
X   *PS_NEWSuse the NeWS server to render pictures/bounding boxes
X   *PS_GSuse GhostScript to render pictures/bounding boxes
X+  *SELFILEsupport for the SelFile selection widget
X   */
X  
X  #ifndeflint
X***************
X*** 1197,1202 ****
X--- 1198,1209 ----
X      cr_Pixel = string_to_pixel(&resource.curs_color);
X  
X  #endif/* TOOLKIT */
X+ 
X+ #ifdefSELFILE
X+ /* There isn't a filename by here, so pop up a selection box  JSP */
X+ if (dvi_name == NULL)
X+     (void) select_filename(False, False);
X+ #endif/* SELFILE */
X  
X  if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 ||
X  dvi_name == NULL) usage();
Xdiff -c xdvi18_old/xdvi.h xdvi18/xdvi.h
X*** xdvi18_old/xdvi.hSat Mar 11 22:33:46 1995
X--- xdvi18/xdvi.hMon Mar 13 17:40:54 1995
X***************
X*** 575,580 ****
X--- 575,586 ----
X  #defineallow_can0xff
X  #endif
X  
X+ #ifdefSELFILE
X+ #ifdef  TOOLKIT
X+ EXTERNchar*title_nameINIT(NULL);
X+ #endif  /* TOOLKIT */
X+ #endif/* SELFILE */
X+ 
X  structWindowRec {
X  Windowwin;
X  intshrinkfactor;
X
SHAR_EOF
chmod 0644 xdvipl18_epsbox+elepsf+selfile+vikey.patch || echo "restore of xdvipl18_epsbox+elepsf+selfile+vikey.patch fails"
sed 's/^X//' << 'SHAR_EOF' > Dir.c &&
X/*
X * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Software Research Associates not be used
X * in advertising or publicity pertaining to distribution of the software
X * without specific, written prior permission.  Software Research Associates
X * makes no representations about the suitability of this software for any
X * purpose.  It is provided "as is" without express or implied warranty.
X *
X * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
X * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Erik M. van der Poel
X *         Software Research Associates, Inc., Tokyo, Japan
X *         erik@sra.co.jp
X */
X
X#include <stdio.h>
X
X#ifdef SEL_FILE_IGNORE_CASE
X#include <ctype.h>
X#endif /* def SEL_FILE_IGNORE_CASE */
X
X#include "SFinternal.h"
X
X#if defined(SVR4) || defined(SYSV) || defined(USG) || defined(__osf__)
X#include <dirent.h>
X#else /* defined(SVR4) || defined(SYSV) || defined(USG) */
X#include <sys/dir.h>
X#define dirent direct
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
X#include <sys/stat.h>
X
X#if defined(SVR4) || defined(SYSV) || defined(USG)
Xextern void qsort();
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
X#ifdef SEL_FILE_IGNORE_CASE
Xint
XSFcompareEntries(p, q)
XSFEntry*p;
XSFEntry*q;
X{
Xregister char*r, *s;
Xregister charc1, c2;
X
Xr = p->real;
Xs = q->real;
X
Xc1 = *r++;
Xif (islower(c1)) {
Xc1 = toupper(c1);
X}
Xc2 = *s++;
Xif (islower(c2)) {
Xc2 = toupper(c2);
X}
X
Xwhile (c1 == c2) {
Xif (!c1) {
Xreturn strcmp(p->real, q->real);
X}
Xc1 = *r++;
Xif (islower(c1)) {
Xc1 = toupper(c1);
X}
Xc2 = *s++;
Xif (islower(c2)) {
Xc2 = toupper(c2);
X}
X}
X
Xreturn c1 - c2;
X}
X#else /* def SEL_FILE_IGNORE_CASE */
Xint
XSFcompareEntries(p, q)
XSFEntry*p;
XSFEntry*q;
X{
Xreturn strcmp(p->real, q->real);
X}
X#endif /* def SEL_FILE_IGNORE_CASE */
X
Xint
XSFgetDir(dir)
XSFDir*dir;
X{
XSFEntry*result = NULL;
Xintalloc = 0;
Xinti;
XDIR*dirp;
Xstruct dirent*dp;
Xchar*str;
Xintlen;
XintmaxChars;
Xstruct statstatBuf;
X
XmaxChars = strlen(dir->dir) - 1;
X
Xdir->entries = NULL;
Xdir->nEntries = 0;
Xdir->nChars = 0;
X
Xresult = NULL;
Xi = 0;
X
Xdirp = opendir(".");
Xif (!dirp) {
Xreturn 1;
X}
X
X(void) stat(".", &statBuf);
Xdir->mtime = statBuf.st_mtime;
X
X(void) readdir(dirp);/* throw away "." */
X
X#ifndef S_IFLNK
X(void) readdir(dirp);/* throw away ".." */
X#endif /* ndef S_IFLNK */
X
Xwhile (dp = readdir(dirp)) {
Xif (i >= alloc) {
Xalloc = 2 * (alloc + 1);
Xresult = (SFEntry *) XtRealloc((char *) result,
X(unsigned) (alloc * sizeof(SFEntry)));
X}
Xresult[i].statDone = 0;
Xstr = dp->d_name;
Xlen = strlen(str);
Xresult[i].real = XtMalloc((unsigned) (len + 2));
X(void) strcat(strcpy(result[i].real, str), " ");
Xif (len > maxChars) {
XmaxChars = len;
X}
Xresult[i].shown = result[i].real;
Xi++;
X}
X
X#if defined(SVR4) || defined(SYSV) || defined(USG)
Xqsort((char *) result, (unsigned) i, sizeof(SFEntry), SFcompareEntries);
X#else /* defined(SVR4) || defined(SYSV) || defined(USG) */
Xqsort((char *) result, i, sizeof(SFEntry), SFcompareEntries);
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
Xdir->entries = result;
Xdir->nEntries = i;
Xdir->nChars = maxChars + 1;
X
Xclosedir(dirp);
X
Xreturn 0;
X}
SHAR_EOF
chmod 0644 Dir.c || echo "restore of Dir.c fails"
sed 's/^X//' << 'SHAR_EOF' > Draw.c &&
X/*
X * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Software Research Associates not be used
X * in advertising or publicity pertaining to distribution of the software
X * without specific, written prior permission.  Software Research Associates
X * makes no representations about the suitability of this software for any
X * purpose.  It is provided "as is" without express or implied warranty.
X *
X * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
X * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Erik M. van der Poel
X *         Software Research Associates, Inc., Tokyo, Japan
X *         erik@sra.co.jp
X */
X
X#include <stdio.h>
X#include "SFinternal.h"
X#include "xstat.h"
X#include <X11/StringDefs.h>
X#include <X11/Xaw/Scrollbar.h>
X#include <X11/Xaw/Cardinals.h>
X
X#define SF_DEFAULT_FONT "9x15"
X
X#ifdef ABS
X#undef ABS
X#endif
X#define ABS(x) (((x) < 0) ? (-(x)) : (x))
X
Xtypedef struct {
Xchar *fontname;
X} TextData, *textPtr;
X
Xint SFcharWidth, SFcharAscent, SFcharHeight;
X
Xint SFcurrentInvert[3] = { -1, -1, -1 };
X
Xstatic GC SFlineGC, SFscrollGC, SFinvertGC, SFtextGC;
X
Xstatic XtResource textResources[] = {
X{XtNfont, XtCFont, XtRString, sizeof (char *),
XXtOffset(textPtr, fontname), XtRString, SF_DEFAULT_FONT},
X};
X
Xstatic XFontStruct *SFfont;
X
Xstatic int SFcurrentListY;
X
Xstatic XtIntervalId SFscrollTimerId;
X
XSFinitFont()
X{
XTextData*data;
X
Xdata = XtNew(TextData);
X
XXtGetApplicationResources(selFileForm, (XtPointer) data, textResources,
XXtNumber(textResources), (Arg *) NULL, ZERO);
X
XSFfont = XLoadQueryFont(SFdisplay, data->fontname);
Xif (!SFfont) {
XSFfont = XLoadQueryFont(SFdisplay, SF_DEFAULT_FONT);
Xif (!SFfont) {
Xcharsbuf[256];
X
X(void) sprintf(sbuf, "XsraSelFile: can't get font %s",
XSF_DEFAULT_FONT);
X
XXtAppError(SFapp, sbuf);
X}
X}
X
XSFcharWidth = (SFfont->max_bounds.width + SFfont->min_bounds.width) / 2;
XSFcharAscent = SFfont->max_bounds.ascent;
XSFcharHeight = SFcharAscent + SFfont->max_bounds.descent;
X}
X
XSFcreateGC()
X{
XXGCValuesgcValues;
XXRectanglerectangles[1];
X
XgcValues.foreground = SFfore;
X
XSFlineGC = XtGetGC(
XselFileLists[0],
X(XtGCMask)
XGCForeground|
X0,
X&gcValues
X);
X
XSFscrollGC = XtGetGC(
XselFileLists[0],
X(XtGCMask)
X0,
X&gcValues
X);
X
XgcValues.function = GXinvert;
XgcValues.plane_mask = (SFfore ^ SFback);
X
XSFinvertGC = XtGetGC(
XselFileLists[0],
X(XtGCMask)
XGCFunction|
XGCPlaneMask|
X0,
X&gcValues
X);
X
XgcValues.foreground = SFfore;
XgcValues.background = SFback;
XgcValues.font = SFfont->fid;
X
XSFtextGC = XCreateGC(
XSFdisplay,
XXtWindow(selFileLists[0]),
X(unsigned long)
XGCForeground|
XGCBackground|
XGCFont|
X0,
X&gcValues
X);
X
Xrectangles[0].x = SFlineToTextH + SFbesideText;
Xrectangles[0].y = 0;
Xrectangles[0].width = SFcharsPerEntry * SFcharWidth;
Xrectangles[0].height = SFupperY + 1;
X
XXSetClipRectangles(
XSFdisplay,
XSFtextGC,
X0,
X0,
Xrectangles,
X1,
XUnsorted
X);
X}
X
XSFclearList(n, doScroll)
Xintn;
XintdoScroll;
X{
XSFDir*dir;
X
XSFcurrentInvert[n] = -1;
X
XXClearWindow(SFdisplay, XtWindow(selFileLists[n]));
X
XXDrawSegments(SFdisplay, XtWindow(selFileLists[n]), SFlineGC, SFsegs,
X2);
X
Xif (doScroll) {
Xdir = &(SFdirs[SFdirPtr + n]);
X
Xif ((SFdirPtr + n < SFdirEnd) && dir->nEntries && dir->nChars) {
XXawScrollbarSetThumb(
XselFileVScrolls[n],
X(float) (((double) dir->vOrigin) /
Xdir->nEntries),
X(float) (((double) ((dir->nEntries < SFlistSize)
X? dir->nEntries : SFlistSize)) /
Xdir->nEntries)
X);
X
XXawScrollbarSetThumb(
XselFileHScrolls[n],
X(float) (((double) dir->hOrigin) / dir->nChars),
X(float) (((double) ((dir->nChars <
XSFcharsPerEntry) ? dir->nChars :
XSFcharsPerEntry)) / dir->nChars)
X);
X} else {
XXawScrollbarSetThumb(selFileVScrolls[n], (float) 0.0,
X(float) 1.0);
XXawScrollbarSetThumb(selFileHScrolls[n], (float) 0.0,
X(float) 1.0);
X}
X}
X}
X
Xstatic
XSFdeleteEntry(dir, entry)
XSFDir*dir;
XSFEntry*entry;
X{
Xregister SFEntry*e;
Xregister SFEntry*end;
Xintn;
Xintidx;
X
Xidx = entry - dir->entries;
X
Xif (idx < dir->beginSelection) {
Xdir->beginSelection--;
X}
Xif (idx <= dir->endSelection) {
Xdir->endSelection--;
X}
Xif (dir->beginSelection > dir->endSelection) {
Xdir->beginSelection = dir->endSelection = -1;
X}
X
Xif (idx < dir->vOrigin) {
Xdir->vOrigin--;
X}
X
XXtFree(entry->real);
X
Xend = &(dir->entries[dir->nEntries - 1]);
X
Xfor (e = entry; e < end; e++) {
X*e = *(e + 1);
X}
X
Xif (!(--dir->nEntries)) {
Xreturn;
X}
X
Xn = dir - &(SFdirs[SFdirPtr]);
Xif ((n < 0) || (n > 2)) {
Xreturn;
X}
X
XXawScrollbarSetThumb(
XselFileVScrolls[n],
X(float) (((double) dir->vOrigin) / dir->nEntries),
X(float) (((double) ((dir->nEntries < SFlistSize) ?
Xdir->nEntries : SFlistSize)) / dir->nEntries)
X);
X}
X
Xstatic
XSFwriteStatChar(name, last, statBuf)
Xchar*name;
Xintlast;
Xstruct stat*statBuf;
X{
Xname[last] = SFstatChar(statBuf);
X}
X
Xstatic int
XSFstatAndCheck(dir, entry)
XSFDir*dir;
XSFEntry*entry;
X{
Xstruct statstatBuf;
Xcharsave;
Xintlast;
X
X/*
X * must be restored before returning
X */
Xsave = *(dir->path);
X*(dir->path) = 0;
X
Xif (!SFchdir(SFcurrentPath)) {
Xlast = strlen(entry->real) - 1;
Xentry->real[last] = 0;
Xentry->statDone = 1;
Xif (
X(!stat(entry->real, &statBuf))
X
X#ifdef S_IFLNK
X
X     || (!lstat(entry->real, &statBuf))
X
X#endif /* ndef S_IFLNK */
X
X) {
Xif (SFfunc) {
Xchar *shown;
X
Xshown = NULL;
Xif (SFfunc(entry->real, &shown, &statBuf)) {
Xif (shown) {
Xint len;
X
Xlen = strlen(shown);
Xentry->shown = XtMalloc(
X(unsigned) (len + 2)
X);
X(void) strcpy(entry->shown,
Xshown);
XSFwriteStatChar(
Xentry->shown,
Xlen,
X&statBuf
X);
Xentry->shown[len + 1] = 0;
X}
X} else {
XSFdeleteEntry(dir, entry);
X
X*(dir->path) = save;
Xreturn 1;
X}
X}
XSFwriteStatChar(entry->real, last, &statBuf);
X} else {
Xentry->real[last] = ' ';
X}
X}
X
X*(dir->path) = save;
Xreturn 0;
X}
X
Xstatic
XSFdrawStrings(w, dir, from, to)
Xregister Windoww;
Xregister SFDir*dir;
Xregister intfrom;
Xregister intto;
X{
Xregister inti;
Xregister SFEntry*entry;
Xintx;
X
Xx = SFtextX - dir->hOrigin * SFcharWidth;
X
Xif (dir->vOrigin + to >= dir->nEntries) {
Xto = dir->nEntries - dir->vOrigin - 1;
X}
Xfor (i = from; i <= to; i++) {
Xentry = &(dir->entries[dir->vOrigin + i]);
Xif (!(entry->statDone)) {
Xif (SFstatAndCheck(dir, entry)) {
Xif (dir->vOrigin + to >= dir->nEntries) {
Xto = dir->nEntries - dir->vOrigin - 1;
X}
Xi--;
Xcontinue;
X}
X}
XXDrawImageString(
XSFdisplay,
Xw,
XSFtextGC,
Xx,
XSFtextYoffset + i * SFentryHeight,
Xentry->shown,
Xstrlen(entry->shown)
X);
Xif (dir->vOrigin + i == dir->beginSelection) {
XXDrawLine(
XSFdisplay,
Xw,
XSFlineGC,
XSFlineToTextH + 1,
XSFlowerY + i * SFentryHeight,
XSFlineToTextH + SFentryWidth - 2,
XSFlowerY + i * SFentryHeight
X);
X}
Xif (
X(dir->vOrigin + i >= dir->beginSelection) &&
X(dir->vOrigin + i <= dir->endSelection)
X) {
XSFcompletionSegs[0].y1 = SFcompletionSegs[1].y1 =
XSFlowerY + i * SFentryHeight;
XSFcompletionSegs[0].y2 = SFcompletionSegs[1].y2 =
XSFlowerY + (i + 1) * SFentryHeight - 1;
XXDrawSegments(
XSFdisplay,
Xw,
XSFlineGC,
XSFcompletionSegs,
X2
X);
X}
Xif (dir->vOrigin + i == dir->endSelection) {
XXDrawLine(
XSFdisplay,
Xw,
XSFlineGC,
XSFlineToTextH + 1,
XSFlowerY + (i + 1) * SFentryHeight - 1,
XSFlineToTextH + SFentryWidth - 2,
XSFlowerY + (i + 1) * SFentryHeight - 1
X);
X}
X}
X}
X
XSFdrawList(n, doScroll)
Xintn;
XintdoScroll;
X{
XSFDir*dir;
XWindoww;
X
XSFclearList(n, doScroll);
X
Xif (SFdirPtr + n < SFdirEnd) {
Xdir = &(SFdirs[SFdirPtr + n]);
Xw = XtWindow(selFileLists[n]);
XXDrawImageString(
XSFdisplay,
Xw,
XSFtextGC,
XSFtextX - dir->hOrigin * SFcharWidth,
XSFlineToTextV + SFaboveAndBelowText + SFcharAscent,
Xdir->dir,
Xstrlen(dir->dir)
X);
XSFdrawStrings(w, dir, 0, SFlistSize - 1);
X}
X}
X
XSFdrawLists(doScroll)
XintdoScroll;
X{
Xinti;
X
Xfor (i = 0; i < 3; i++) {
XSFdrawList(i, doScroll);
X}
X}
X
Xstatic
XSFinvertEntry(n)
Xregister intn;
X{
XXFillRectangle(
XSFdisplay,
XXtWindow(selFileLists[n]),
XSFinvertGC,
XSFlineToTextH,
XSFcurrentInvert[n] * SFentryHeight + SFlowerY,
XSFentryWidth,
XSFentryHeight
X);
X}
X
Xstatic unsigned long
XSFscrollTimerInterval()
X{
Xstatic intmaxVal = 200;
Xstatic intvaryDist = 50;
Xstatic intminDist = 50;
Xintt;
Xintdist;
X
Xif (SFcurrentListY < SFlowerY) {
Xdist = SFlowerY - SFcurrentListY;
X} else if (SFcurrentListY > SFupperY) {
Xdist = SFcurrentListY - SFupperY;
X} else {
Xreturn (unsigned long) 1;
X}
X
Xt = maxVal - ((maxVal / varyDist) * (dist - minDist));
X
Xif (t < 1) {
Xt = 1;
X}
X
Xif (t > maxVal) {
Xt = maxVal;
X}
X
Xreturn (unsigned long) t;
X}
X
Xstatic void
XSFscrollTimer(p, id)
XXtPointerp;
X        XtIntervalId    *id;
X{
XSFDir*dir;
Xintsave;
Xint     n;
X
X        n = (int) p;
X
Xdir = &(SFdirs[SFdirPtr + n]);
Xsave = dir->vOrigin;
X
Xif (SFcurrentListY < SFlowerY) {
Xif (dir->vOrigin > 0) {
XSFvSliderMovedCallback(selFileVScrolls[n], n,
Xdir->vOrigin - 1);
X}
X} else if (SFcurrentListY > SFupperY) {
Xif (dir->vOrigin < dir->nEntries - SFlistSize) {
XSFvSliderMovedCallback(selFileVScrolls[n], n,
Xdir->vOrigin + 1);
X}
X}
X
Xif (dir->vOrigin != save) {
Xif (dir->nEntries) {
X    XawScrollbarSetThumb(
XselFileVScrolls[n],
X(float) (((double) dir->vOrigin) / dir->nEntries),
X(float) (((double) ((dir->nEntries < SFlistSize) ?
Xdir->nEntries : SFlistSize)) / dir->nEntries)
X    );
X}
X}
X
Xif (SFbuttonPressed) {
XSFscrollTimerId = XtAppAddTimeOut(SFapp,
XSFscrollTimerInterval(), SFscrollTimer, (XtPointer) n);
X}
X}
X
Xstatic int
XSFnewInvertEntry(n, event)
Xregister intn;
Xregister XMotionEvent*event;
X{
Xregister intx, y;
Xregister intnew;
Xstatic intSFscrollTimerAdded = 0;
X
Xx = event->x;
Xy = event->y;
X
Xif (SFdirPtr + n >= SFdirEnd) {
Xreturn -1;
X} else if (
X(x >= 0)&& (x <= SFupperX) &&
X(y >= SFlowerY)&& (y <= SFupperY)
X) {
Xregister SFDir *dir = &(SFdirs[SFdirPtr + n]);
X
Xif (SFscrollTimerAdded) {
XSFscrollTimerAdded = 0;
XXtRemoveTimeOut(SFscrollTimerId);
X}
X
Xnew = (y - SFlowerY) / SFentryHeight;
Xif (dir->vOrigin + new >= dir->nEntries) {
Xreturn -1;
X}
Xreturn new;
X} else {
Xif (SFbuttonPressed) {
XSFcurrentListY = y;
Xif (!SFscrollTimerAdded) {
XSFscrollTimerAdded = 1;
XSFscrollTimerId = XtAppAddTimeOut(SFapp,
XSFscrollTimerInterval(), SFscrollTimer,
X(XtPointer) n);
X}
X}
X
Xreturn -1;
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFenterList(w, n, event)
XWidgetw;
Xregister intn;
Xregister XEnterWindowEvent*event;
X{
Xregister intnew;
X
X/* sanity */
Xif (SFcurrentInvert[n] != -1) {
XSFinvertEntry(n);
XSFcurrentInvert[n] = -1;
X}
X
Xnew = SFnewInvertEntry(n, (XMotionEvent *) event);
Xif (new != -1) {
XSFcurrentInvert[n] = new;
XSFinvertEntry(n);
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFleaveList(w, n, event)
XWidgetw;
Xregister intn;
XXEvent*event;
X{
Xif (SFcurrentInvert[n] != -1) {
XSFinvertEntry(n);
XSFcurrentInvert[n] = -1;
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFmotionList(w, n, event)
XWidgetw;
Xregister intn;
Xregister XMotionEvent*event;
X{
Xregister intnew;
X
Xnew = SFnewInvertEntry(n, event);
X
Xif (new != SFcurrentInvert[n]) {
Xif (SFcurrentInvert[n] != -1) {
XSFinvertEntry(n);
X}
XSFcurrentInvert[n] = new;
Xif (new != -1) {
XSFinvertEntry(n);
X}
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFvFloatSliderMovedCallback(w, n, fnew)
XWidgetw;
Xintn;
Xfloat*fnew;
X{
Xintnew;
X
Xnew = (*fnew) * SFdirs[SFdirPtr + n].nEntries;
X
XSFvSliderMovedCallback(w, n, new);
X}
X
X/* ARGSUSED */
Xvoid
XSFvSliderMovedCallback(w, n, new)
XWidgetw;
Xintn;
Xintnew;
X{
Xintold;
Xregister Windowwin;
XSFDir*dir;
X
Xdir = &(SFdirs[SFdirPtr + n]);
X
Xold = dir->vOrigin;
Xdir->vOrigin = new;
X
Xif (old == new) {
Xreturn;
X}
X
Xwin = XtWindow(selFileLists[n]);
X
Xif (ABS(new - old) < SFlistSize) {
Xif (new > old) {
XXCopyArea(
XSFdisplay,
Xwin,
Xwin,
XSFscrollGC,
XSFlineToTextH,
XSFlowerY + (new - old) * SFentryHeight,
XSFentryWidth + SFlineToTextH,
X(SFlistSize - (new - old)) * SFentryHeight,
XSFlineToTextH,
XSFlowerY
X);
XXClearArea(
XSFdisplay,
Xwin,
XSFlineToTextH,
XSFlowerY + (SFlistSize - (new - old)) *
XSFentryHeight,
XSFentryWidth + SFlineToTextH,
X(new - old) * SFentryHeight,
XFalse
X);
XSFdrawStrings(win, dir, SFlistSize - (new - old),
XSFlistSize - 1);
X} else {
XXCopyArea(
XSFdisplay,
Xwin,
Xwin,
XSFscrollGC,
XSFlineToTextH,
XSFlowerY,
XSFentryWidth + SFlineToTextH,
X(SFlistSize - (old - new)) * SFentryHeight,
XSFlineToTextH,
XSFlowerY + (old - new) * SFentryHeight
X);
XXClearArea(
XSFdisplay,
Xwin,
XSFlineToTextH,
XSFlowerY,
XSFentryWidth + SFlineToTextH,
X(old - new) * SFentryHeight,
XFalse
X);
XSFdrawStrings(win, dir, 0, old - new);
X}
X} else {
XXClearArea(
XSFdisplay,
Xwin,
XSFlineToTextH,
XSFlowerY,
XSFentryWidth + SFlineToTextH,
XSFlistSize * SFentryHeight,
XFalse
X);
XSFdrawStrings(win, dir, 0, SFlistSize - 1);
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFvAreaSelectedCallback(w, n, pnew)
XWidgetw;
Xintn;
Xintpnew;
X{
XSFDir*dir;
Xintnew;
X
Xdir = &(SFdirs[SFdirPtr + n]);
X
Xnew = dir->vOrigin +
X(((double) pnew) / SFvScrollHeight) * dir->nEntries;
X
Xif (new > dir->nEntries - SFlistSize) {
Xnew = dir->nEntries - SFlistSize;
X}
X
Xif (new < 0) {
Xnew = 0;
X}
X
Xif (dir->nEntries) {
Xfloatf;
X
Xf = ((double) new) / dir->nEntries;
X
XXawScrollbarSetThumb(
Xw,
Xf,
X(float) (((double) ((dir->nEntries < SFlistSize) ?
Xdir->nEntries : SFlistSize)) / dir->nEntries)
X);
X}
X
XSFvSliderMovedCallback(w, n, new);
X}
X
X/* ARGSUSED */
Xvoid
XSFhSliderMovedCallback(w, n, new)
XWidgetw;
Xintn;
Xfloat*new;
X{
XSFDir*dir;
Xintsave;
X
Xdir = &(SFdirs[SFdirPtr + n]);
Xsave = dir->hOrigin;
Xdir->hOrigin = (*new) * dir->nChars;
Xif (dir->hOrigin == save) {
Xreturn;
X}
X
XSFdrawList(n, SF_DO_NOT_SCROLL);
X}
X
X/* ARGSUSED */
Xvoid
XSFhAreaSelectedCallback(w, n, pnew)
XWidgetw;
Xintn;
Xintpnew;
X{
XSFDir*dir;
Xintnew;
X
Xdir = &(SFdirs[SFdirPtr + n]);
X
Xnew = dir->hOrigin +
X(((double) pnew) / SFhScrollWidth) * dir->nChars;
X
Xif (new > dir->nChars - SFcharsPerEntry) {
Xnew = dir->nChars - SFcharsPerEntry;
X}
X
Xif (new < 0) {
Xnew = 0;
X}
X
Xif (dir->nChars) {
Xfloatf;
X
Xf = ((double) new) / dir->nChars;
X
XXawScrollbarSetThumb(
Xw,
Xf,
X(float) (((double) ((dir->nChars < SFcharsPerEntry) ?
Xdir->nChars : SFcharsPerEntry)) / dir->nChars)
X);
X
XSFhSliderMovedCallback(w, n, &f);
X}
X}
X
X/* ARGSUSED */
Xvoid
XSFpathSliderMovedCallback(w, client_data, new)
XWidgetw;
XXtPointerclient_data;
Xfloat*new;
X{
XSFDir*dir;
Xintn;
XXawTextPositionpos;
XintSFdirPtrSave;
X
XSFdirPtrSave = SFdirPtr;
XSFdirPtr = (*new) * SFdirEnd;
Xif (SFdirPtr == SFdirPtrSave) {
Xreturn;
X}
X
XSFdrawLists(SF_DO_SCROLL);
X
Xn = 2;
Xwhile (SFdirPtr + n >= SFdirEnd) {
Xn--;
X}
X
Xdir = &(SFdirs[SFdirPtr + n]);
X
Xpos = dir->path - SFcurrentPath;
X
Xif (!strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) {
Xpos -= strlen(SFstartDir);
Xif (pos < 0) {
Xpos = 0;
X}
X}
X
XXawTextSetInsertionPoint(selFileField, pos);
X}
X
X/* ARGSUSED */
X
Xvoid
XSFpathAreaSelectedCallback(w, client_data, pnew)
XWidgetw;
XXtPointerclient_data;
Xintpnew;
X{
Xintnew;
Xfloatf;
X
Xnew = SFdirPtr + (((double) pnew) / SFpathScrollWidth) * SFdirEnd;
X
Xif (new > SFdirEnd - 3) {
Xnew = SFdirEnd - 3;
X}
X
Xif (new < 0) {
Xnew = 0;
X}
X
Xf = ((double) new) / SFdirEnd;
X
XXawScrollbarSetThumb(
Xw,
Xf,
X(float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) /
XSFdirEnd)
X);
X
XSFpathSliderMovedCallback(w, (XtPointer) NULL, &f);
X}
X
XBoolean
XSFworkProc()
X{
Xregister SFDir*dir;
Xregister SFEntry*entry;
X
Xfor (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--) {
Xif (!(dir->nEntries)) {
Xcontinue;
X}
Xfor (
Xentry = &(dir->entries[dir->nEntries - 1]);
Xentry >= dir->entries;
Xentry--
X) {
Xif (!(entry->statDone)) {
X(void) SFstatAndCheck(dir, entry);
Xreturn False;
X}
X}
X}
X
XSFworkProcAdded = 0;
X
Xreturn True;
X}
SHAR_EOF
chmod 0644 Draw.c || echo "restore of Draw.c fails"
sed 's/^X//' << 'SHAR_EOF' > Path.c &&
X/*
X * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Software Research Associates not be used
X * in advertising or publicity pertaining to distribution of the software
X * without specific, written prior permission.  Software Research Associates
X * makes no representations about the suitability of this software for any
X * purpose.  It is provided "as is" without express or implied warranty.
X *
X * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
X * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Erik M. van der Poel
X *         Software Research Associates, Inc., Tokyo, Japan
X *         erik@sra.co.jp
X */
X
X#include <stdio.h>
X
X#ifdef SEL_FILE_IGNORE_CASE
X#include <ctype.h>
X#endif /* def SEL_FILE_IGNORE_CASE */
X
X#include <X11/Xos.h>
X#include <pwd.h>
X#include "SFinternal.h"
X#include "xstat.h"
X#include <X11/Xaw/Scrollbar.h>
X
X#if defined(SVR4) || defined(SYSV) || defined(USG)
Xextern uid_t getuid();
Xextern void qsort();
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
Xtypedef struct {
Xchar*name;
Xchar*dir;
X} SFLogin;
X
XSFDir *SFdirs = NULL;
X
Xint SFdirEnd;
X
Xint SFdirPtr;
X
Xint SFbuttonPressed = 0;
X
Xstatic int SFdoNotTouchDirPtr = 0;
X
Xstatic int SFdoNotTouchVorigin = 0;
X
Xstatic SFDir SFrootDir, SFhomeDir;
X
Xstatic SFLogin *SFlogins;
X
Xstatic int SFtwiddle = 0;
X
Xint
XSFchdir(path)
Xchar*path;
X{
Xintresult;
X
Xresult = 0;
X
Xif (strcmp(path, SFcurrentDir)) {
Xresult = chdir(path);
Xif (!result) {
X(void) strcpy(SFcurrentDir, path);
X}
X}
X
Xreturn result;
X}
X
Xstatic
XSFfree(i)
Xinti;
X{
Xregister SFDir*dir;
Xregister intj;
X
Xdir = &(SFdirs[i]);
X
Xfor (j = dir->nEntries - 1; j >= 0; j--) {
Xif (dir->entries[j].shown != dir->entries[j].real) {
XXtFree(dir->entries[j].shown);
X}
XXtFree(dir->entries[j].real);
X}
X
XXtFree((char *) dir->entries);
X
XXtFree(dir->dir);
X
Xdir->dir = NULL;
X}
X
Xstatic
XSFstrdup(s1, s2)
Xchar**s1;
Xchar*s2;
X{
X*s1 = strcpy(XtMalloc((unsigned) (strlen(s2) + 1)), s2);
X}
X
Xstatic
XSFunreadableDir(dir)
XSFDir*dir;
X{
Xchar*cannotOpen = "<cannot open> ";
X
Xdir->entries = (SFEntry *) XtMalloc(sizeof(SFEntry));
Xdir->entries[0].statDone = 1;
XSFstrdup(&dir->entries[0].real, cannotOpen);
Xdir->entries[0].shown = dir->entries[0].real;
Xdir->nEntries = 1;
Xdir->nChars = strlen(cannotOpen);
X}
X
X#ifdef SEL_FILE_IGNORE_CASE
Xstatic
XSFstrncmp(p, q, n)
Xregister char*p, *q;
Xregister intn;
X{
Xregister charc1, c2;
Xchar*psave, *qsave;
Xintnsave;
X
Xpsave = p;
Xqsave = q;
Xnsave = n;
X
Xc1 = *p++;
Xif (islower(c1)) {
Xc1 = toupper(c1);
X}
Xc2 = *q++;
Xif (islower(c2)) {
Xc2 = toupper(c2);
X}
X
Xwhile ((--n >= 0) && (c1 == c2)) {
Xif (!c1) {
Xreturn strncmp(psave, qsave, nsave);
X}
Xc1 = *p++;
Xif (islower(c1)) {
Xc1 = toupper(c1);
X}
Xc2 = *q++;
Xif (islower(c2)) {
Xc2 = toupper(c2);
X}
X}
X
Xif (n < 0) {
Xreturn strncmp(psave, qsave, nsave);
X}
X
Xreturn c1 - c2;
X}
X#endif /* def SEL_FILE_IGNORE_CASE */
X
Xstatic
XSFreplaceText(dir, str)
XSFDir*dir;
Xchar*str;
X{
Xintlen;
X
X*(dir->path) = 0;
Xlen = strlen(str);
Xif (str[len - 1] == '/') {
X(void) strcat(SFcurrentPath, str);
X} else {
X(void) strncat(SFcurrentPath, str, len - 1);
X}
Xif (strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) {
XSFsetText(SFcurrentPath);
X} else {
XSFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
X}
X
XSFtextChanged();
X}
X
Xstatic void
XSFexpand(str)
Xchar*str;
X{
Xintlen;
Xintcmp;
Xchar*name, *growing;
XSFDir*dir;
XSFEntry*entry, *max;
X
Xlen = strlen(str);
X
Xdir = &(SFdirs[SFdirEnd - 1]);
X
Xif (dir->beginSelection == -1) {
XSFstrdup(&str, str);
XSFreplaceText(dir, str);
XXtFree(str);
Xreturn;
X} else if (dir->beginSelection == dir->endSelection) {
XSFreplaceText(dir, dir->entries[dir->beginSelection].shown);
Xreturn;
X}
X
Xmax = &(dir->entries[dir->endSelection + 1]);
X
Xname = dir->entries[dir->beginSelection].shown;
XSFstrdup(&growing, name);
X
Xcmp = 0;
Xwhile (!cmp) {
Xentry = &(dir->entries[dir->beginSelection]);
Xwhile (entry < max) {
Xif (cmp = strncmp(growing, entry->shown, len)) {
Xbreak;
X}
Xentry++;
X}
Xlen++;
X}
X
X/*
X * SFreplaceText() expects filename
X */
Xgrowing[len - 2] = ' ';
X
Xgrowing[len - 1] = 0;
XSFreplaceText(dir, growing);
XXtFree(growing);
X}
X
Xstatic int
XSFfindFile(dir, str)
XSFDir*dir;
Xregister char*str;
X{
Xregister inti, last, max;
Xregister char*name, save;
XSFEntry*entries;
Xintlen;
Xintbegin, end;
Xintresult;
X
Xlen = strlen(str);
X
Xif (str[len - 1] == ' ') {
XSFexpand(str);
Xreturn 1;
X} else if (str[len - 1] == '/') {
Xlen--;
X}
X
Xmax = dir->nEntries;
X
Xentries = dir->entries;
X
Xi = 0;
Xwhile (i < max) {
Xname = entries[i].shown;
Xlast = strlen(name) - 1;
Xsave = name[last];
Xname[last] = 0;
X
X#ifdef SEL_FILE_IGNORE_CASE
Xresult = SFstrncmp(str, name, len);
X#else /* def SEL_FILE_IGNORE_CASE */
Xresult = strncmp(str, name, len);
X#endif /* def SEL_FILE_IGNORE_CASE */
X
Xname[last] = save;
Xif (result <= 0) {
Xbreak;
X}
Xi++;
X}
Xbegin = i;
Xwhile (i < max) {
Xname = entries[i].shown;
Xlast = strlen(name) - 1;
Xsave = name[last];
Xname[last] = 0;
X
X#ifdef SEL_FILE_IGNORE_CASE
Xresult = SFstrncmp(str, name, len);
X#else /* def SEL_FILE_IGNORE_CASE */
Xresult = strncmp(str, name, len);
X#endif /* def SEL_FILE_IGNORE_CASE */
X
Xname[last] = save;
Xif (result) {
Xbreak;
X}
Xi++;
X}
Xend = i;
X
Xif (begin != end) {
Xif (
X(dir->beginSelection != begin) ||
X(dir->endSelection != end - 1)
X) {
Xdir->changed = 1;
Xdir->beginSelection = begin;
Xif (str[strlen(str) - 1] == '/') {
Xdir->endSelection = begin;
X} else {
Xdir->endSelection = end - 1;
X}
X}
X} else {
Xif (dir->beginSelection != -1) {
Xdir->changed = 1;
Xdir->beginSelection = -1;
Xdir->endSelection = -1;
X}
X}
X
Xif (
XSFdoNotTouchVorigin ||
X((begin > dir->vOrigin) && (end < dir->vOrigin + SFlistSize))
X) {
XSFdoNotTouchVorigin = 0;
Xreturn 0;
X}
X
Xi = begin - 1;
Xif (i > max - SFlistSize) {
Xi = max - SFlistSize;
X}
Xif (i < 0) {
Xi = 0;
X}
X
Xif (dir->vOrigin != i) {
Xdir->vOrigin = i;
Xdir->changed = 1;
X}
X
Xreturn 0;
X}
X
Xstatic
XSFunselect()
X{
XSFDir*dir;
X
Xdir = &(SFdirs[SFdirEnd - 1]);
Xif (dir->beginSelection != -1) {
Xdir->changed = 1;
X}
Xdir->beginSelection = -1;
Xdir->endSelection = -1;
X}
X
Xstatic int
XSFcompareLogins(p, q)
XSFLogin*p, *q;
X{
Xreturn strcmp(p->name, q->name);
X}
X
Xstatic
XSFgetHomeDirs()
X{
Xstruct passwd*pw;
Xintalloc;
Xinti;
XSFEntry*entries = NULL;
Xintlen;
XintmaxChars;
X
X{
Xalloc = 1;
Xi = 1;
Xentries = (SFEntry *) XtMalloc(sizeof(SFEntry));
XSFlogins = (SFLogin *) XtMalloc(sizeof(SFLogin));
Xentries[0].real = XtMalloc(3);
X(void) strcpy(entries[0].real, "~");
Xentries[0].shown = entries[0].real;
Xentries[0].statDone = 1;
XSFlogins[0].name = "";
Xpw = getpwuid((int) getuid());
XSFstrdup(&SFlogins[0].dir, pw ? pw->pw_dir : "/");
XmaxChars = 0;
X}
X
X(void) setpwent();
X
Xwhile ((pw = getpwent()) && (*(pw->pw_name))) {
Xif (i >= alloc) {
Xalloc *= 2;
Xentries = (SFEntry *) XtRealloc(
X(char *) entries,
X(unsigned) (alloc * sizeof(SFEntry))
X);
XSFlogins = (SFLogin *) XtRealloc(
X(char *) SFlogins,
X(unsigned) (alloc * sizeof(SFLogin))
X);
X}
Xlen = strlen(pw->pw_name);
Xentries[i].real = XtMalloc((unsigned) (len + 3));
X(void) strcat(strcpy(entries[i].real, "~"),
Xpw->pw_name);
Xentries[i].shown = entries[i].real;
Xentries[i].statDone = 1;
Xif (len > maxChars) {
XmaxChars = len;
X}
XSFstrdup(&SFlogins[i].name, pw->pw_name);
XSFstrdup(&SFlogins[i].dir, pw->pw_dir);
Xi++;
X}
X
XSFhomeDir.dir= XtMalloc(1);
XSFhomeDir.dir[0]= 0;
XSFhomeDir.path= SFcurrentPath;
XSFhomeDir.entries= entries;
XSFhomeDir.nEntries= i;
XSFhomeDir.vOrigin= 0;/* :-) */
XSFhomeDir.nChars= maxChars + 2;
XSFhomeDir.hOrigin= 0;
XSFhomeDir.changed= 1;
XSFhomeDir.beginSelection= -1;
XSFhomeDir.endSelection= -1;
X
X#if defined(SVR4) || defined(SYSV) || defined(USG)
Xqsort((char *) entries, (unsigned)i, sizeof(SFEntry), SFcompareEntries);
Xqsort((char *) SFlogins, (unsigned)i, sizeof(SFLogin), SFcompareLogins);
X#else /* defined(SVR4) || defined(SYSV) || defined(USG) */
Xqsort((char *) entries, i, sizeof(SFEntry), SFcompareEntries);
Xqsort((char *) SFlogins, i, sizeof(SFLogin), SFcompareLogins);
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
Xfor (i--; i >= 0; i--) {
X(void) strcat(entries[i].real, "/");
X}
X}
X
Xstatic int
XSFfindHomeDir(begin, end)
Xchar*begin, *end;
X{
Xcharsave;
Xchar*theRest;
Xinti;
X
Xsave = *end;
X*end = 0;
X
Xfor (i = SFhomeDir.nEntries - 1; i >= 0; i--) {
Xif (!strcmp(SFhomeDir.entries[i].real, begin)) {
X*end = save;
XSFstrdup(&theRest, end);
X(void) strcat(strcat(strcpy(SFcurrentPath,
XSFlogins[i].dir), "/"), theRest);
XXtFree(theRest);
XSFsetText(SFcurrentPath);
XSFtextChanged();
Xreturn 1;
X}
X}
X
X*end = save;
X
Xreturn 0;
X}
X
XSFupdatePath()
X{
Xstatic intalloc;
Xstatic intwasTwiddle = 0;
Xchar*begin, *end;
Xinti, j;
XintprevChange;
XintSFdirPtrSave, SFdirEndSave;
XSFDir*dir;
X
Xif (!SFdirs) {
XSFdirs = (SFDir *) XtMalloc((alloc = 10) * sizeof(SFDir));
Xdir = &(SFdirs[0]);
XSFstrdup(&dir->dir, "/");
X(void) SFchdir("/");
X(void) SFgetDir(dir);
Xfor (j = 1; j < alloc; j++) {
XSFdirs[j].dir = NULL;
X}
Xdir->path = SFcurrentPath + 1;
Xdir->vOrigin = 0;
Xdir->hOrigin = 0;
Xdir->changed = 1;
Xdir->beginSelection = -1;
Xdir->endSelection = -1;
XSFhomeDir.dir = NULL;
X}
X
XSFdirEndSave = SFdirEnd;
XSFdirEnd = 1;
X
XSFdirPtrSave = SFdirPtr;
XSFdirPtr = 0;
X
Xbegin = NULL;
X
Xif (SFcurrentPath[0] == '~') {
Xif (!SFtwiddle) {
XSFtwiddle = 1;
Xdir = &(SFdirs[0]);
XSFrootDir = *dir;
Xif (!SFhomeDir.dir) {
XSFgetHomeDirs();
X}
X*dir = SFhomeDir;
Xdir->changed = 1;
X}
Xend = SFcurrentPath;
XSFdoNotTouchDirPtr = 1;
XwasTwiddle = 1;
X} else {
Xif (SFtwiddle) {
XSFtwiddle = 0;
Xdir = &(SFdirs[0]);
X*dir = SFrootDir;
Xdir->changed = 1;
X}
Xend = SFcurrentPath + 1;
X}
X
Xi = 0;
X
XprevChange = 0;
X
Xwhile (*end) {
Xwhile (*end++ == '/') {
X;
X}
Xend--;
Xbegin = end;
Xwhile ((*end) && (*end++ != '/')) {
X;
X}
Xif ((end - SFcurrentPath <= SFtextPos) && (*(end - 1) == '/')) {
XSFdirPtr = i - 1;
Xif (SFdirPtr < 0) {
XSFdirPtr = 0;
X}
X}
Xif (*begin) {
Xif (*(end - 1) == '/') {
Xchar save = *end;
X
Xif (SFtwiddle) {
Xif (SFfindHomeDir(begin, end)) {
Xreturn;
X}
X}
X*end = 0;
Xi++;
XSFdirEnd++;
Xif (i >= alloc) {
XSFdirs = (SFDir *) XtRealloc(
X(char *) SFdirs,
X(unsigned) ((alloc *= 2) *
Xsizeof(SFDir))
X);
Xfor (j = alloc / 2; j < alloc; j++) {
XSFdirs[j].dir = NULL;
X}
X}
Xdir = &(SFdirs[i]);
Xif (
X(!(dir->dir)) ||
XprevChange ||
Xstrcmp(dir->dir, begin)
X) {
Xif (dir->dir) {
XSFfree(i);
X}
XprevChange = 1;
XSFstrdup(&dir->dir, begin);
Xdir->path = end;
Xdir->vOrigin = 0;
Xdir->hOrigin = 0;
Xdir->changed = 1;
Xdir->beginSelection = -1;
Xdir->endSelection = -1;
X(void) SFfindFile(dir - 1, begin);
Xif (
XSFchdir(SFcurrentPath) ||
XSFgetDir(dir)
X) {
XSFunreadableDir(dir);
Xbreak;
X}
X}
X*end = save;
Xif (!save) {
XSFunselect();
X}
X} else {
Xif (SFfindFile(&(SFdirs[SFdirEnd-1]), begin)) {
Xreturn;
X}
X}
X} else {
XSFunselect();
X}
X}
X
Xif ((end == SFcurrentPath + 1) && (!SFtwiddle)) {
XSFunselect();
X}
X
Xfor (i = SFdirEnd; i < alloc; i++) {
Xif (SFdirs[i].dir) {
XSFfree(i);
X}
X}
X
Xif (SFdoNotTouchDirPtr) {
Xif (wasTwiddle) {
XwasTwiddle = 0;
XSFdirPtr = SFdirEnd - 2;
Xif (SFdirPtr < 0) {
XSFdirPtr = 0;
X}
X} else {
XSFdirPtr = SFdirPtrSave;
X}
XSFdoNotTouchDirPtr = 0;
X}
X
Xif ((SFdirPtr != SFdirPtrSave) || (SFdirEnd != SFdirEndSave)) {
XXawScrollbarSetThumb(
XselFileHScroll,
X(float) (((double) SFdirPtr) / SFdirEnd),
X(float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) /
XSFdirEnd)
X);
X}
X
Xif (SFdirPtr != SFdirPtrSave) {
XSFdrawLists(SF_DO_SCROLL);
X} else {
Xfor (i = 0; i < 3; i++) {
Xif (SFdirPtr + i < SFdirEnd) {
Xif (SFdirs[SFdirPtr + i].changed) {
XSFdirs[SFdirPtr + i].changed = 0;
XSFdrawList(i, SF_DO_SCROLL);
X}
X} else {
XSFclearList(i, SF_DO_SCROLL);
X}
X}
X}
X}
X
XSFsetText(path)
Xchar*path;
X{
XXawTextBlocktext;
X
Xtext.firstPos = 0;
Xtext.length = strlen(path);
Xtext.ptr = path;
Xtext.format = FMT8BIT;
X
XXawTextReplace(selFileField, 0, strlen(SFtextBuffer), &text);
XXawTextSetInsertionPoint(selFileField, strlen(SFtextBuffer));
X}
X
X/* ARGSUSED */
Xvoid
XSFbuttonPressList(w, n, event)
XWidgetw;
Xintn;
XXButtonPressedEvent*event;
X{
XSFbuttonPressed = 1;
X}
X
X/* ARGSUSED */
Xvoid
XSFbuttonReleaseList(w, n, event)
XWidgetw;
Xintn;
XXButtonReleasedEvent*event;
X{
XSFDir*dir;
X
XSFbuttonPressed = 0;
X
Xif (SFcurrentInvert[n] != -1) {
Xif (n < 2) {
XSFdoNotTouchDirPtr = 1;
X}
XSFdoNotTouchVorigin = 1;
Xdir = &(SFdirs[SFdirPtr + n]);
XSFreplaceText(
Xdir,
Xdir->entries[dir->vOrigin + SFcurrentInvert[n]].shown
X);
XSFmotionList(w, n, event);
X}
X}
X
Xstatic int
XSFcheckDir(n, dir)
Xintn;
XSFDir*dir;
X{
Xstruct statstatBuf;
Xinti;
X
Xif (
X(!stat(".", &statBuf)) &&
X(statBuf.st_mtime != dir->mtime)
X) {
X
X/*
X * If the pointer is currently in the window that we are about
X * to update, we must warp it to prevent the user from
X * accidentally selecting the wrong file.
X */
Xif (SFcurrentInvert[n] != -1) {
XXWarpPointer(
XSFdisplay,
XNone,
XXtWindow(selFileLists[n]),
X0,
X0,
X0,
X0,
X0,
X0
X);
X}
X
Xfor (i = dir->nEntries - 1; i >= 0; i--) {
Xif (dir->entries[i].shown != dir->entries[i].real) {
XXtFree(dir->entries[i].shown);
X}
XXtFree(dir->entries[i].real);
X}
XXtFree((char *) dir->entries);
Xif (SFgetDir(dir)) {
XSFunreadableDir(dir);
X}
Xif (dir->vOrigin > dir->nEntries - SFlistSize) {
Xdir->vOrigin = dir->nEntries - SFlistSize;
X}
Xif (dir->vOrigin < 0) {
Xdir->vOrigin = 0;
X}
Xif (dir->hOrigin > dir->nChars - SFcharsPerEntry) {
Xdir->hOrigin = dir->nChars - SFcharsPerEntry;
X}
Xif (dir->hOrigin < 0) {
Xdir->hOrigin = 0;
X}
Xdir->beginSelection = -1;
Xdir->endSelection = -1;
XSFdoNotTouchVorigin = 1;
Xif ((dir + 1)->dir) {
X(void) SFfindFile(dir, (dir + 1)->dir);
X} else {
X(void) SFfindFile(dir, dir->path);
X}
X
Xif (!SFworkProcAdded) {
X(void) XtAppAddWorkProc(SFapp, SFworkProc, NULL);
XSFworkProcAdded = 1;
X}
X
Xreturn 1;
X}
X
Xreturn 0;
X}
X
Xstatic int
XSFcheckFiles(dir)
XSFDir*dir;
X{
Xintfrom, to;
Xintresult;
Xcharold, new;
Xinti;
Xchar*str;
Xintlast;
Xstruct statstatBuf;
X
Xresult = 0;
X
Xfrom = dir->vOrigin;
Xto = dir->vOrigin + SFlistSize;
Xif (to > dir->nEntries) {
Xto = dir->nEntries;
X}
X
Xfor (i = from; i < to; i++) {
Xstr = dir->entries[i].real;
Xlast = strlen(str) - 1;
Xold = str[last];
Xstr[last] = 0;
Xif (stat(str, &statBuf)) {
Xnew = ' ';
X} else {
Xnew = SFstatChar(&statBuf);
X}
Xstr[last] = new;
Xif (new != old) {
Xresult = 1;
X}
X}
X
Xreturn result;
X}
X
Xvoid
XSFdirModTimer(cl, id)
X        XtPointer       cl;
X        XtIntervalId    *id;
X{
Xstatic intn = -1;
Xstatic intf = 0;
Xcharsave;
XSFDir*dir;
X
Xif ((!SFtwiddle) && (SFdirPtr < SFdirEnd)) {
Xn++;
Xif ((n > 2) || (SFdirPtr + n >= SFdirEnd)) {
Xn = 0;
Xf++;
Xif ((f > 2) || (SFdirPtr + f >= SFdirEnd)) {
Xf = 0;
X}
X}
Xdir = &(SFdirs[SFdirPtr + n]);
Xsave = *(dir->path);
X*(dir->path) = 0;
Xif (SFchdir(SFcurrentPath)) {
X*(dir->path) = save;
X
X/*
X * force a re-read
X */
X*(dir->dir) = 0;
X
XSFupdatePath();
X} else {
X*(dir->path) = save;
Xif (
XSFcheckDir(n, dir) ||
X((f == n) && SFcheckFiles(dir))
X) {
XSFdrawList(n, SF_DO_SCROLL);
X}
X}
X}
X
XSFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000,
XSFdirModTimer, (XtPointer) NULL);
X}
X
X/* Return a single character describing what kind of file STATBUF is.  */
X
Xchar
XSFstatChar (statBuf)
Xstruct stat *statBuf;
X{
Xif (S_ISDIR (statBuf->st_mode)) {
Xreturn '/';
X} else if (S_ISREG (statBuf->st_mode)) {
X  return S_ISXXX (statBuf->st_mode) ? '*' : ' ';
X#ifdef S_ISSOCK
X} else if (S_ISSOCK (statBuf->st_mode)) {
Xreturn '=';
X#endif /* S_ISSOCK */
X} else {
Xreturn ' ';
X}
X}
SHAR_EOF
chmod 0644 Path.c || echo "restore of Path.c fails"
sed 's/^X//' << 'SHAR_EOF' > SFinternal.h &&
X/*
X * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Software Research Associates not be used
X * in advertising or publicity pertaining to distribution of the software
X * without specific, written prior permission.  Software Research Associates
X * makes no representations about the suitability of this software for any
X * purpose.  It is provided "as is" without express or implied warranty.
X *
X * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
X * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Erik M. van der Poel
X *         Software Research Associates, Inc., Tokyo, Japan
X *         erik@sra.co.jp
X */
X
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Xos.h>
X#include <X11/Xaw/Text.h>
X#include <X11/Xaw/AsciiText.h>
X
X#define SEL_FILE_CANCEL-1
X#define SEL_FILE_OK0
X#define SEL_FILE_NULL1
X#define SEL_FILE_TEXT2
X
X#define SF_DO_SCROLL1
X#define SF_DO_NOT_SCROLL0
X
Xtypedef struct {
XintstatDone;
Xchar*real;
Xchar*shown;
X} SFEntry;
X
Xtypedef struct {
Xchar*dir;
Xchar*path;
XSFEntry*entries;
XintnEntries;
XintvOrigin;
XintnChars;
XinthOrigin;
Xintchanged;
XintbeginSelection;
XintendSelection;
Xtime_tmtime;
X} SFDir;
X
Xextern int SFstatus;
X
Xextern char SFcurrentPath[], SFstartDir[], SFcurrentDir[];
X
Xextern Widget
XselFile,
XselFileCancel,
XselFileField,
XselFileForm,
XselFileHScroll,
XselFileHScrolls[],
XselFileLists[],
XselFileOK,
XselFilePrompt,
XselFileVScrolls[];
X
Xextern Display *SFdisplay;
X
Xextern int SFcharWidth, SFcharHeight, SFcharAscent;
X
Xextern SFDir *SFdirs;
X
Xextern int SFdirEnd, SFdirPtr;
X
Xextern Pixel SFfore, SFback;
X
Xextern Atom SFwmDeleteWindow;
X
Xextern XSegment SFsegs[], SFcompletionSegs[];
X
Xextern XawTextPosition SFtextPos;
X
Xextern void
XSFenterList(),
XSFleaveList(),
XSFmotionList(),
XSFbuttonPressList(),
XSFbuttonReleaseList();
X
Xextern void
XSFvSliderMovedCallback(),
XSFvFloatSliderMovedCallback(),
XSFhSliderMovedCallback(),
XSFpathSliderMovedCallback(),
XSFvAreaSelectedCallback(),
XSFhAreaSelectedCallback(),
XSFpathAreaSelectedCallback();
X
Xextern int SFupperX, SFlowerY, SFupperY;
X
Xextern int SFtextX, SFtextYoffset;
X
Xextern int SFentryWidth, SFentryHeight;
X
Xextern int SFlineToTextH, SFlineToTextV;
X
Xextern int SFbesideText, SFaboveAndBelowText;
X
Xextern int SFcharsPerEntry;
X
Xextern int SFlistSize;
X
Xextern int SFcurrentInvert[];
X
Xextern int SFworkProcAdded;
X
Xextern Boolean SFworkProc();
X
Xextern XtAppContext SFapp;
X
Xextern int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
X
Xextern char SFtextBuffer[];
X
Xextern int SFbuttonPressed;
X
Xextern int SFcompareEntries();
X
Xextern void SFdirModTimer();
X
Xextern char SFstatChar();
X
Xextern XtIntervalId SFdirModTimerId;
X
Xextern int (*SFfunc)();
SHAR_EOF
chmod 0644 SFinternal.h || echo "restore of SFinternal.h fails"
sed 's/^X//' << 'SHAR_EOF' > SelFile.c &&
X/*
X * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Software Research Associates not be used
X * in advertising or publicity pertaining to distribution of the software
X * without specific, written prior permission.  Software Research Associates
X * makes no representations about the suitability of this software for any
X * purpose.  It is provided "as is" without express or implied warranty.
X *
X * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
X * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Erik M. van der Poel
X *         Software Research Associates, Inc., Tokyo, Japan
X *         erik@sra.co.jp
X */
X
X/*
X * Author's address:
X *
X *     erik@sra.co.jp
X *                                            OR
X *     erik%sra.co.jp@uunet.uu.net
X *                                            OR
X *     erik%sra.co.jp@mcvax.uucp
X *                                            OR
X *     try junet instead of co.jp
X *                                            OR
X *     Erik M. van der Poel
X *     Software Research Associates, Inc.
X *     1-1-1 Hirakawa-cho, Chiyoda-ku
X *     Tokyo 102 Japan. TEL +81-3-234-2692
X */
X
X#include <stdio.h>
X#include <errno.h>
X/* BSD 4.3 errno.h does not declare errno */
Xextern int errno;
Xextern int sys_nerr;
Xextern char *sys_errlist[];
X
X#include <sys/param.h>
X#include <X11/cursorfont.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Composite.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Scrollbar.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/Cardinals.h>
X
X#include "SFinternal.h"
X
X#ifndef MAXPATHLEN
X#define MAXPATHLEN 1024
X#endif /* ndef MAXPATHLEN */
X
X#if !defined(SVR4) && !defined(SYSV) && !defined(USG)
Xextern char *getwd();
X#endif /* !defined(SVR4) && !defined(SYSV) && !defined(USG) */
X
Xint SFstatus = SEL_FILE_NULL;
X
Xchar
XSFstartDir[MAXPATHLEN],
XSFcurrentPath[MAXPATHLEN],
XSFcurrentDir[MAXPATHLEN];
X
XWidget
XselFile,
XselFileCancel,
XselFileField,
XselFileForm,
XselFileHScroll,
XselFileHScrolls[3],
XselFileLists[3],
XselFileOK,
XselFilePrompt,
XselFileVScrolls[3];
X
XDisplay *SFdisplay;
X
XPixel SFfore, SFback;
X
XAtomSFwmDeleteWindow;
X
XXSegment SFsegs[2], SFcompletionSegs[2];
X
XXawTextPosition SFtextPos;
X
Xint SFupperX, SFlowerY, SFupperY;
X
Xint SFtextX, SFtextYoffset;
X
Xint SFentryWidth, SFentryHeight;
X
Xint SFlineToTextH = 3;
X
Xint SFlineToTextV = 3;
X
Xint SFbesideText = 3;
X
Xint SFaboveAndBelowText = 2;
X
Xint SFcharsPerEntry = 15;
X
Xint SFlistSize = 10;
X
Xint SFworkProcAdded = 0;
X
XXtAppContext SFapp;
X
Xint SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
X
Xchar SFtextBuffer[MAXPATHLEN];
X
XXtIntervalId SFdirModTimerId;
X
Xint (*SFfunc)();
X
Xstatic char *oneLineTextEditTranslations = "\
X<Key>Return:redraw-display()\n\
XCtrl<Key>M:redraw-display()\n\
X";
X
X/* ARGSUSED */
Xstatic void
XSFexposeList(w, n, event, cont)
XWidgetw;
XXtPointern;
X        XEvent   *event;
X        Boolean         *cont;
X{
Xif ((event->type == NoExpose) || event->xexpose.count) {
Xreturn;
X}
X
XSFdrawList(n, SF_DO_NOT_SCROLL);
X}
X
X/* ARGSUSED */
Xstatic void
XSFmodVerifyCallback(w, client_data, event, cont)
XWidgetw;
XXtPointerclient_data;
X        XEvent                *event;
X        Boolean                 *cont;
X{
Xcharbuf[2];
X
Xif (
X(XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) &&
X((*buf) == '\r')
X) {
XSFstatus = SEL_FILE_OK;
X} else {
XSFstatus = SEL_FILE_TEXT;
X}
X}
X
X/* ARGSUSED */
Xstatic void
XSFokCallback(w, cl, cd)
XWidgetw;
X        XtPointer cl, cd;
X{
XSFstatus = SEL_FILE_OK;
X}
X
Xstatic XtCallbackRec SFokSelect[] = {
X{ SFokCallback, (XtPointer) NULL },
X{ NULL, (XtPointer) NULL },
X};
X
X/* ARGSUSED */
Xstatic void
XSFcancelCallback(w, cl, cd)
XWidgetw;
X        XtPointer cl, cd;
X{
XSFstatus = SEL_FILE_CANCEL;
X}
X
Xstatic XtCallbackRec SFcancelSelect[] = {
X{ SFcancelCallback, (XtPointer) NULL },
X{ NULL, (XtPointer) NULL },
X};
X
X/* ARGSUSED */
Xstatic void
XSFdismissAction(w, event, params, num_params)
XWidgetw;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
Xif (event->type == ClientMessage &&
X    event->xclient.data.l[0] != SFwmDeleteWindow) return;
X
XSFstatus = SEL_FILE_CANCEL;
X}
X
Xstatic char *wmDeleteWindowTranslation = "\
X<Message>WM_PROTOCOLS:SelFileDismiss()\n\
X";
X
Xstatic XtActionsRec actions[] = {
X{"SelFileDismiss",SFdismissAction},
X};
X
Xstatic void
XSFcreateWidgets(toplevel, prompt, ok, cancel)
XWidgettoplevel;
Xchar*prompt;
Xchar*ok;
Xchar*cancel;
X{
XCardinali, n;
XintlistWidth, listHeight;
XintlistSpacing = 10;
XintscrollThickness = 15;
XinthScrollX, hScrollY;
XintvScrollX, vScrollY;
XCursor
XxtermCursor,
XsbRightArrowCursor,
XdotCursor;
XArgarglist[20];
X
Xi = 0;
XXtSetArg(arglist[i], XtNtransientFor, toplevel);i++;
X
XselFile = XtAppCreateShell("selFile", "SelFile",
XtransientShellWidgetClass, SFdisplay, arglist, i);
X
X/* Add WM_DELETE_WINDOW protocol */
XXtAppAddActions(XtWidgetToApplicationContext(selFile),
Xactions, XtNumber(actions));
XXtOverrideTranslations(selFile,
XXtParseTranslationTable(wmDeleteWindowTranslation));
X
Xi = 0;
XXtSetArg(arglist[i], XtNdefaultDistance, 30);i++;
XselFileForm = XtCreateManagedWidget("selFileForm",
XformWidgetClass, selFile, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNlabel, prompt);i++;
XXtSetArg(arglist[i], XtNresizable, True);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNborderWidth, 0);i++;
XselFilePrompt = XtCreateManagedWidget("selFilePrompt",
XlabelWidgetClass, selFileForm, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNforeground, &SFfore);i++;
XXtSetArg(arglist[i], XtNbackground, &SFback);i++;
XXtGetValues(selFilePrompt, arglist, i);
X
XSFinitFont();
X
XSFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth +
XSFbesideText;
XSFentryHeight = SFaboveAndBelowText + SFcharHeight +
XSFaboveAndBelowText;
X
XlistWidth = SFlineToTextH + SFentryWidth + SFlineToTextH + 1 +
XscrollThickness;
XlistHeight = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
XSFlineToTextV + SFlistSize * SFentryHeight +
XSFlineToTextV + 1 + scrollThickness;
X
XSFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4;
X
XhScrollX = -1;
XhScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
XSFlineToTextV + SFlistSize * SFentryHeight +
XSFlineToTextV;
XSFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH;
X
XvScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH;
XvScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV;
XSFvScrollHeight = SFlineToTextV + SFlistSize * SFentryHeight +
XSFlineToTextV;
X
XSFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1;
XSFlowerY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
XSFlineToTextV;
XSFupperY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
XSFlineToTextV + SFlistSize * SFentryHeight - 1;
X
XSFtextX = SFlineToTextH + SFbesideText;
XSFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent;
X
XSFsegs[0].x1 = 0;
XSFsegs[0].y1 = vScrollY;
XSFsegs[0].x2 = vScrollX - 1;
XSFsegs[0].y2 = vScrollY;
XSFsegs[1].x1 = vScrollX;
XSFsegs[1].y1 = 0;
XSFsegs[1].x2 = vScrollX;
XSFsegs[1].y2 = vScrollY - 1;
X
XSFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH;
XSFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 =
XSFlineToTextH + SFentryWidth - 1;
X
Xi = 0;
XXtSetArg(arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4);
Xi++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
X
XXtSetArg(arglist[i], XtNfromVert, selFilePrompt);i++;
XXtSetArg(arglist[i], XtNvertDistance, 10);i++;
XXtSetArg(arglist[i], XtNresizable, True);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNstring, SFtextBuffer);i++;
XXtSetArg(arglist[i], XtNlength, MAXPATHLEN);i++;
XXtSetArg(arglist[i], XtNeditType, XawtextEdit);i++;
XXtSetArg(arglist[i], XtNwrap, XawtextWrapWord);i++;
XXtSetArg(arglist[i], XtNresize, XawtextResizeHeight);i++;
XXtSetArg(arglist[i], XtNuseStringInPlace, True);i++;
XselFileField = XtCreateManagedWidget("selFileField",
XasciiTextWidgetClass, selFileForm, arglist, i);
X
XXtOverrideTranslations(selFileField,
XXtParseTranslationTable(oneLineTextEditTranslations));
XXtSetKeyboardFocus(selFileForm, selFileField);
X
Xi = 0;
XXtSetArg(arglist[i], XtNorientation, XtorientHorizontal);i++;
XXtSetArg(arglist[i], XtNwidth, SFpathScrollWidth);i++;
XXtSetArg(arglist[i], XtNheight, scrollThickness);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileField);i++;
XXtSetArg(arglist[i], XtNvertDistance, 30);i++;
XXtSetArg(arglist[i], XtNhorizDistance, 30);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileHScroll = XtCreateManagedWidget("selFileHScroll",
XscrollbarWidgetClass, selFileForm, arglist, i);
X
XXtAddCallback(selFileHScroll, XtNjumpProc,
XSFpathSliderMovedCallback, (XtPointer) NULL);
XXtAddCallback(selFileHScroll, XtNscrollProc,
XSFpathAreaSelectedCallback, (XtPointer) NULL);
X
Xi = 0;
XXtSetArg(arglist[i], XtNwidth, listWidth);i++;
XXtSetArg(arglist[i], XtNheight, listHeight);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileHScroll);i++;
XXtSetArg(arglist[i], XtNvertDistance, 10);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileLists[0] = XtCreateManagedWidget("selFileList1",
XcompositeWidgetClass, selFileForm, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNwidth, listWidth);i++;
XXtSetArg(arglist[i], XtNheight, listHeight);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromHoriz, selFileLists[0]);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileHScroll);i++;
XXtSetArg(arglist[i], XtNhorizDistance, listSpacing);i++;
XXtSetArg(arglist[i], XtNvertDistance, 10);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileLists[1] = XtCreateManagedWidget("selFileList2",
XcompositeWidgetClass, selFileForm, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNwidth, listWidth);i++;
XXtSetArg(arglist[i], XtNheight, listHeight);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromHoriz, selFileLists[1]);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileHScroll);i++;
XXtSetArg(arglist[i], XtNhorizDistance, listSpacing);i++;
XXtSetArg(arglist[i], XtNvertDistance, 10);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileLists[2] = XtCreateManagedWidget("selFileList3",
XcompositeWidgetClass, selFileForm, arglist, i);
X
Xfor (n = 0; n < 3; n++) {
X
Xi = 0;
XXtSetArg(arglist[i], XtNx, vScrollX);i++;
XXtSetArg(arglist[i], XtNy, vScrollY);i++;
XXtSetArg(arglist[i], XtNwidth, scrollThickness);i++;
XXtSetArg(arglist[i], XtNheight, SFvScrollHeight);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XselFileVScrolls[n] = XtCreateManagedWidget("selFileVScroll",
XscrollbarWidgetClass, selFileLists[n], arglist, i);
X
XXtAddCallback(selFileVScrolls[n], XtNjumpProc,
XSFvFloatSliderMovedCallback, (XtPointer) n);
XXtAddCallback(selFileVScrolls[n], XtNscrollProc,
XSFvAreaSelectedCallback, (XtPointer) n);
X
Xi = 0;
X
XXtSetArg(arglist[i], XtNorientation, XtorientHorizontal);
Xi++;
XXtSetArg(arglist[i], XtNx, hScrollX);i++;
XXtSetArg(arglist[i], XtNy, hScrollY);i++;
XXtSetArg(arglist[i], XtNwidth, SFhScrollWidth);i++;
XXtSetArg(arglist[i], XtNheight, scrollThickness);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XselFileHScrolls[n] = XtCreateManagedWidget("selFileHScroll",
XscrollbarWidgetClass, selFileLists[n], arglist, i);
X
XXtAddCallback(selFileHScrolls[n], XtNjumpProc,
XSFhSliderMovedCallback, (XtPointer) n);
XXtAddCallback(selFileHScrolls[n], XtNscrollProc,
XSFhAreaSelectedCallback, (XtPointer) n);
X}
X
Xi = 0;
XXtSetArg(arglist[i], XtNlabel, ok);i++;
XXtSetArg(arglist[i], XtNresizable, True);i++;
XXtSetArg(arglist[i], XtNcallback, SFokSelect);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileLists[0]);i++;
XXtSetArg(arglist[i], XtNvertDistance, 30);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileOK = XtCreateManagedWidget("selFileOK", commandWidgetClass,
XselFileForm, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNlabel, cancel);i++;
XXtSetArg(arglist[i], XtNresizable, True);i++;
XXtSetArg(arglist[i], XtNcallback, SFcancelSelect);i++;
XXtSetArg(arglist[i], XtNborderColor, SFfore);i++;
XXtSetArg(arglist[i], XtNfromHoriz, selFileOK);i++;
XXtSetArg(arglist[i], XtNfromVert, selFileLists[0]);i++;
XXtSetArg(arglist[i], XtNhorizDistance, 30);i++;
XXtSetArg(arglist[i], XtNvertDistance, 30);i++;
XXtSetArg(arglist[i], XtNtop, XtChainTop);i++;
XXtSetArg(arglist[i], XtNbottom, XtChainTop);i++;
XXtSetArg(arglist[i], XtNleft, XtChainLeft);i++;
XXtSetArg(arglist[i], XtNright, XtChainLeft);i++;
XselFileCancel = XtCreateManagedWidget("selFileCancel",
XcommandWidgetClass, selFileForm, arglist, i);
X
XXtSetMappedWhenManaged(selFile, False);
XXtRealizeWidget(selFile);
X
X/* Add WM_DELETE_WINDOW protocol */
XSFwmDeleteWindow = XInternAtom(SFdisplay, "WM_DELETE_WINDOW", False);
XXSetWMProtocols(SFdisplay, XtWindow(selFile), &SFwmDeleteWindow, 1);
X
XSFcreateGC();
X
XxtermCursor = XCreateFontCursor(SFdisplay, XC_xterm);
X
XsbRightArrowCursor = XCreateFontCursor(SFdisplay, XC_sb_right_arrow);
XdotCursor = XCreateFontCursor(SFdisplay, XC_dot);
X
XXDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor);
XXDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor);
X
Xfor (n = 0; n < 3; n++) {
XXDefineCursor(SFdisplay, XtWindow(selFileLists[n]),
XsbRightArrowCursor);
X}
XXDefineCursor(SFdisplay, XtWindow(selFileOK), dotCursor);
XXDefineCursor(SFdisplay, XtWindow(selFileCancel), dotCursor);
X
Xfor (n = 0; n < 3; n++) {
XXtAddEventHandler(selFileLists[n], ExposureMask, True,
XSFexposeList, (XtPointer) n);
XXtAddEventHandler(selFileLists[n], EnterWindowMask, False,
XSFenterList, (XtPointer) n);
XXtAddEventHandler(selFileLists[n], LeaveWindowMask, False,
XSFleaveList, (XtPointer) n);
XXtAddEventHandler(selFileLists[n], PointerMotionMask, False,
XSFmotionList, (XtPointer) n);
XXtAddEventHandler(selFileLists[n], ButtonPressMask, False,
XSFbuttonPressList, (XtPointer) n);
XXtAddEventHandler(selFileLists[n], ButtonReleaseMask, False,
XSFbuttonReleaseList, (XtPointer) n);
X}
X
XXtAddEventHandler(selFileField, KeyPressMask, False,
XSFmodVerifyCallback, (XtPointer) NULL);
X
XSFapp = XtWidgetToApplicationContext(selFile);
X
X}
X
X/* position widget under the cursor */
Xvoid
XSFpositionWidget(w)
X    Widget w;
X{
X    Arg args[3];
X    Cardinal num_args;
X    Dimension width, height, b_width;
X    int x, y, max_x, max_y;
X    Window root, child;
X    int dummyx, dummyy;
X    unsigned int dummymask;
X    
X    XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
X  &dummyx, &dummyy, &dummymask);
X    num_args = 0;
X    XtSetArg(args[num_args], XtNwidth, &width); num_args++;
X    XtSetArg(args[num_args], XtNheight, &height); num_args++;
X    XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
X    XtGetValues(w, args, num_args);
X
X    width += 2 * b_width;
X    height += 2 * b_width;
X
X    x -= ( (Position) width/2 );
X    if (x < 0) x = 0;
X    if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
X
X    y -= ( (Position) height/2 );
X    if (y < 0) y = 0;
X    if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
X    
X    num_args = 0;
X    XtSetArg(args[num_args], XtNx, x); num_args++;
X    XtSetArg(args[num_args], XtNy, y); num_args++;
X    XtSetValues(w, args, num_args);
X}
X
XFILE *
XSFopenFile(name, mode, prompt, failed)
X    char *name;
X    char *mode;
X    char *prompt;
X    char *failed;
X{
X    Arg args[1];
X    FILE *fp;
X
X    SFchdir(SFstartDir);
X    if ((fp = fopen(name, mode)) == NULL) {
Xchar *buf;
Xif (errno <= sys_nerr) {
X    buf = XtMalloc(strlen(failed) + strlen(sys_errlist[errno]) + 
X   strlen(prompt) + 2);
X    strcpy(buf, failed);
X    strcat(buf, sys_errlist[errno]);
X    strcat(buf, "\n");
X    strcat(buf, prompt);
X} else {
X    buf = XtMalloc(strlen(failed) + strlen(prompt) + 2);
X    strcpy(buf, failed);
X    strcat(buf, "\n");
X    strcat(buf, prompt);
X}
XXtSetArg(args[0], XtNlabel, buf);
XXtSetValues(selFilePrompt, args, ONE);
XXtFree(buf);
Xreturn NULL;
X    }
X    return fp;
X}
X
XSFtextChanged()
X{
X
Xif ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
X(void) strcpy(SFcurrentPath, SFtextBuffer);
X
XSFtextPos = XawTextGetInsertionPoint(selFileField);
X} else {
X(void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer);
X
XSFtextPos = XawTextGetInsertionPoint(selFileField) +
Xstrlen(SFstartDir);
X}
X
Xif (!SFworkProcAdded) {
X(void) XtAppAddWorkProc(SFapp, SFworkProc, NULL);
XSFworkProcAdded = 1;
X}
X
XSFupdatePath();
X}
X
Xstatic char *
XSFgetText()
X{
Xreturn strcpy(XtMalloc((unsigned) (strlen(SFtextBuffer) + 1)),
XSFtextBuffer);
X}
X
Xstatic
XSFprepareToReturn()
X{
XSFstatus = SEL_FILE_NULL;
XXtRemoveGrab(selFile);
XXtUnmapWidget(selFile);
XXtRemoveTimeOut(SFdirModTimerId);
Xif (SFchdir(SFstartDir)) {
XXtAppError(
XSFapp,
X"XsraSelFile: can't return to current directory"
X);
X}
X}
X
XFILE *
XXsraSelFile(toplevel, prompt, ok, cancel, failed,
X    init_path, mode, show_entry, name_return)
XWidgettoplevel;
Xchar*prompt;
Xchar*ok;
Xchar*cancel;
Xchar*failed;
Xchar*init_path;
Xchar*mode;
Xint(*show_entry)();
Xchar**name_return;
X{
Xstatic intfirstTime = 1;
XCardinali;
XArgarglist[20];
XXEventevent;
XFILE*fp;
X
Xif (!prompt) {
Xprompt = "Pathname:";
X}
X
Xif (!ok) {
Xok = "OK";
X}
X
Xif (!cancel) {
Xcancel = "Cancel";
X}
X
Xif (firstTime) {
XfirstTime = 0;
XSFdisplay = XtDisplay(toplevel);
XSFcreateWidgets(toplevel, prompt, ok, cancel);
X} else {
Xi = 0;
X
XXtSetArg(arglist[i], XtNlabel, prompt);i++;
XXtSetValues(selFilePrompt, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNlabel, ok);i++;
XXtSetValues(selFileOK, arglist, i);
X
Xi = 0;
XXtSetArg(arglist[i], XtNlabel, cancel);i++;
XXtSetValues(selFileCancel, arglist, i);
X}
X
XSFpositionWidget(selFile);
XXtMapWidget(selFile);
X
X#if defined(SVR4) || defined(SYSV) || defined(USG)
Xif (!getcwd(SFstartDir, MAXPATHLEN)) {
X#else /* defined(SVR4) || defined(SYSV) || defined(USG) */
Xif (!getwd(SFstartDir)) {
X#endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
X
XXtAppError(SFapp, "XsraSelFile: can't get current directory");
X}
X(void) strcat(SFstartDir, "/");
X(void) strcpy(SFcurrentDir, SFstartDir);
X
Xif (init_path) {
Xif (init_path[0] == '/') {
X(void) strcpy(SFcurrentPath, init_path);
Xif (strncmp(
XSFcurrentPath,
XSFstartDir,
Xstrlen(SFstartDir)
X)) {
XSFsetText(SFcurrentPath);
X} else {
XSFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
X}
X} else {
X(void) strcat(strcpy(SFcurrentPath, SFstartDir),
Xinit_path);
XSFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
X}
X} else {
X(void) strcpy(SFcurrentPath, SFstartDir);
X}
X
XSFfunc = show_entry;
X
XSFtextChanged();
X
XXtAddGrab(selFile, True, True);
X
XSFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000,
XSFdirModTimer, (XtPointer) NULL);
X
Xwhile (1) {
XXtAppNextEvent(SFapp, &event);
XXtDispatchEvent(&event);
Xswitch (SFstatus) {
Xcase SEL_FILE_TEXT:
XSFstatus = SEL_FILE_NULL;
XSFtextChanged();
Xbreak;
Xcase SEL_FILE_OK:
X*name_return = SFgetText();
Xif (fp = SFopenFile(*name_return, mode,
X    prompt, failed)) {
XSFprepareToReturn();
Xreturn fp;
X}
XSFstatus = SEL_FILE_NULL;
Xbreak;
Xcase SEL_FILE_CANCEL:
XSFprepareToReturn();
Xreturn NULL;
Xcase SEL_FILE_NULL:
Xbreak;
X}
X}
X}
SHAR_EOF
chmod 0644 SelFile.c || echo "restore of SelFile.c fails"
sed 's/^X//' << 'SHAR_EOF' > xstat.h &&
X#include <sys/stat.h>
X#if !defined(S_ISDIR) && defined(S_IFDIR)
X#defineS_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
X#endif
X#if !defined(S_ISREG) && defined(S_IFREG)
X#defineS_ISREG(m) (((m) & S_IFMT) == S_IFREG)
X#endif
X#if !defined(S_ISSOCK) && defined(S_IFSOCK)
X#defineS_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
X#endif
X
X#ifndef S_IXUSR
X#define S_IXUSR 0100
X#endif
X#ifndef S_IXGRP
X#define S_IXGRP 0010
X#endif
X#ifndef S_IXOTH
X#define S_IXOTH 0001
X#endif
X
X#define S_ISXXX(m) ((m) & (S_IXUSR | S_IXGRP | S_IXOTH))
X
SHAR_EOF
chmod 0644 xstat.h || echo "restore of xstat.h fails"
exit 0
---cut here---cut here---cut here---
--
Takanori Uchiyama
Dept. Computer and Systems Engineering, Faculty of Engineering,
KOBE University.
