PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/texlive-2007/texk/windvi/sfSelFile.c

#
C | 940 lines | 741 code | 139 blank | 60 comment | 83 complexity | 3b6e5af33f742141b085077c980be7a1 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, LGPL-3.0, GPL-2.0, CPL-1.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
  3. *
  4. * Permission to use, copy, modify, and distribute this software and its
  5. * documentation for any purpose and without fee is hereby granted, provided
  6. * that the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation, and that the name of Software Research Associates not be used
  9. * in advertising or publicity pertaining to distribution of the software
  10. * without specific, written prior permission. Software Research Associates
  11. * makes no representations about the suitability of this software for any
  12. * purpose. It is provided "as is" without express or implied warranty.
  13. *
  14. * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  15. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  16. * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
  17. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  18. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  19. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20. * PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Author: Erik M. van der Poel
  23. * Software Research Associates, Inc., Tokyo, Japan
  24. * erik@sra.co.jp
  25. */
  26. #ifdef HAVE_CONFIG_H
  27. #include "c-auto.h"
  28. #endif
  29. #if !defined (NOSELFILE) && !defined (NOTOOL) /* for xdvik */
  30. /*
  31. * Author's address:
  32. *
  33. * erik@sra.co.jp
  34. * OR
  35. * erik%sra.co.jp@uunet.uu.net
  36. * OR
  37. * erik%sra.co.jp@mcvax.uucp
  38. * OR
  39. * try junet instead of co.jp
  40. * OR
  41. * Erik M. van der Poel
  42. * Software Research Associates, Inc.
  43. * 1-1-1 Hirakawa-cho, Chiyoda-ku
  44. * Tokyo 102 Japan. TEL +81-3-234-2692
  45. */
  46. #include "xdvi-config.h"
  47. #include <kpathsea/c-stat.h>
  48. #include <sys/param.h>
  49. #include <X11/cursorfont.h>
  50. #include <X11/Intrinsic.h>
  51. #include <X11/StringDefs.h>
  52. #include <X11/Composite.h>
  53. #include <X11/Shell.h>
  54. #include <X11/Xaw/Form.h>
  55. #include <X11/Xaw/Command.h>
  56. #include <X11/Xaw/Scrollbar.h>
  57. #include <X11/Xaw/Label.h>
  58. #include <X11/Xaw/Cardinals.h>
  59. #include "sfinternal.h"
  60. #ifndef MAXPATHLEN
  61. #define MAXPATHLEN 1024
  62. #endif /* ndef MAXPATHLEN */
  63. extern int SFchdir ();
  64. int SFstatus = SEL_FILE_NULL;
  65. char
  66. SFstartDir[MAXPATHLEN],
  67. SFcurrentPath[MAXPATHLEN],
  68. SFcurrentDir[MAXPATHLEN];
  69. Widget
  70. selFile,
  71. selFileCancel,
  72. selFileField,
  73. selFileForm,
  74. selFileHScroll,
  75. selFileHScrolls[3],
  76. selFileLists[3],
  77. selFileOK,
  78. selFilePrompt,
  79. selFileVScrolls[3];
  80. /* For file filter. */
  81. Widget selFileLabel, selFileMask, selFileHide;
  82. #define MASKWIDTH 10
  83. char fileMask[MASKWIDTH+2] = "*.dvi";
  84. Display *SFdisplay;
  85. Pixel SFfore, SFback;
  86. Atom SFwmDeleteWindow;
  87. XSegment SFsegs[2], SFcompletionSegs[2];
  88. XawTextPosition SFtextPos;
  89. int SFupperX, SFlowerY, SFupperY;
  90. int SFtextX, SFtextYoffset;
  91. int SFentryWidth, SFentryHeight;
  92. int SFlineToTextH = 3;
  93. int SFlineToTextV = 3;
  94. int SFbesideText = 3;
  95. int SFaboveAndBelowText = 2;
  96. int SFcharsPerEntry = 15;
  97. int SFlistSize = 10;
  98. int SFworkProcAdded = 0;
  99. XtAppContext SFapp;
  100. int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
  101. char SFtextBuffer[MAXPATHLEN];
  102. XtIntervalId SFdirModTimerId;
  103. int (*SFfunc)();
  104. static char *oneLineTextEditTranslations = "\
  105. <Key>Return: redraw-display()\n\
  106. Ctrl<Key>M: redraw-display()\n\
  107. ";
  108. #if !defined (HAVE_STRERROR) && !defined (strerror)
  109. static char *
  110. strerror (errnum)
  111. int errnum;
  112. {
  113. extern char *sys_errlist[];
  114. extern int sys_nerr;
  115. return 0 < errnum && errnum <= sys_nerr
  116. ? sys_errlist[errnum] : "Unknown system error";
  117. }
  118. #endif /* not HAVE_STRERROR && not strerror */
  119. /* ARGSUSED */
  120. static void
  121. SFexposeList(w, n, event, cont)
  122. Widget w;
  123. XtPointer n;
  124. XEvent *event;
  125. Boolean *cont;
  126. {
  127. extern void SFdrawList ();
  128. if ((event->type == NoExpose) || event->xexpose.count) {
  129. return;
  130. }
  131. SFdrawList(n, SF_DO_NOT_SCROLL);
  132. }
  133. /* ARGSUSED */
  134. static void
  135. SFmodVerifyCallback(w, client_data, event, cont)
  136. Widget w;
  137. XtPointer client_data;
  138. XEvent *event;
  139. Boolean *cont;
  140. {
  141. char buf[2];
  142. if (
  143. (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) &&
  144. ((*buf) == '\r')
  145. ) {
  146. SFstatus = SEL_FILE_OK;
  147. } else {
  148. SFstatus = SEL_FILE_TEXT;
  149. }
  150. }
  151. /* ARGSUSED */
  152. static void
  153. SFokCallback(w, cl, cd)
  154. Widget w;
  155. XtPointer cl, cd;
  156. {
  157. SFstatus = SEL_FILE_OK;
  158. }
  159. static XtCallbackRec SFokSelect[] = {
  160. { SFokCallback, (XtPointer) NULL },
  161. { NULL, (XtPointer) NULL },
  162. };
  163. /* ARGSUSED */
  164. static void
  165. SFcancelCallback(w, cl, cd)
  166. Widget w;
  167. XtPointer cl, cd;
  168. {
  169. SFstatus = SEL_FILE_CANCEL;
  170. }
  171. static XtCallbackRec SFcancelSelect[] = {
  172. { SFcancelCallback, (XtPointer) NULL },
  173. { NULL, (XtPointer) NULL },
  174. };
  175. /* ARGSUSED */
  176. static void
  177. SFdismissAction(w, event, params, num_params)
  178. Widget w;
  179. XEvent *event;
  180. String *params;
  181. Cardinal *num_params;
  182. {
  183. if (event->type == ClientMessage &&
  184. event->xclient.data.l[0] != SFwmDeleteWindow) return;
  185. SFstatus = SEL_FILE_CANCEL;
  186. }
  187. static char *wmDeleteWindowTranslation = "\
  188. <Message>WM_PROTOCOLS: SelFileDismiss()\n\
  189. ";
  190. static XtActionsRec actions[] = {
  191. {"SelFileDismiss", SFdismissAction},
  192. };
  193. /* Don't show files that don't get through the filter. */
  194. int
  195. maskFile(mask, filename)
  196. char *mask, *filename;
  197. /* return 1 if file is masked (mask does not match filename), 0 otherwise */
  198. {
  199. int c, c1;
  200. while ((c = *mask++)) {
  201. if (c == '*') {
  202. while ((c1 = *mask++)) {
  203. if (c1 != '*') {
  204. if (!(*filename)) return 1;
  205. if (c1 != '?') {
  206. while ((filename = strchr(filename, c1))) {
  207. if (!maskFile(mask, ++filename)) return 0;
  208. }
  209. return 1;
  210. }
  211. else filename++;
  212. }
  213. }
  214. return 0;
  215. }
  216. if (c == '?') { if (!*filename) return 1; }
  217. else if (c != *filename) return 1;
  218. filename++;
  219. }
  220. return (*filename)? 1 : 0;
  221. }
  222. int hideFlag = 1;
  223. int
  224. showEntry(entryReal, entryShown, statBuf)
  225. char *entryReal, **entryShown;
  226. struct stat *statBuf;
  227. {
  228. if (!(S_ISDIR(statBuf->st_mode))) {
  229. if (hideFlag)
  230. if (entryReal[0] == '.') return 0;
  231. if (maskFile(fileMask, entryReal)) return 0;
  232. }
  233. entryReal[strlen(entryReal)] = SFstatChar(statBuf);
  234. return 1;
  235. }
  236. /* ARGSUSED */
  237. void
  238. maskChanged(w, client_data, event)
  239. Widget w;
  240. XtPointer client_data;
  241. XKeyPressedEvent *event;
  242. {
  243. char buf[2];
  244. register SFDir *dir;
  245. extern void SFupdatePath ();
  246. if ((XLookupString(event, buf, 2, NULL, NULL) == 1) &&
  247. ((*buf) == '\r')) {
  248. for (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--)
  249. *(dir->dir) = 0; /* force a re-read */
  250. SFupdatePath();
  251. }
  252. }
  253. /* ARGSUSED */
  254. void
  255. hideFiles(w, client_data, event)
  256. Widget w;
  257. XtPointer client_data;
  258. XEvent *event;
  259. {
  260. register SFDir *dir;
  261. register SFEntry *entry;
  262. extern void SFupdatePath (), SFdrawLists ();
  263. hideFlag = 1 - hideFlag;
  264. if (hideFlag) {
  265. XtVaSetValues(w, XtNlabel, "hidden", NULL);
  266. for (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--) {
  267. if (!(dir->nEntries)) continue;
  268. dir->vOrigin = 0;
  269. for (entry = &(dir->entries[dir->nEntries - 1]);
  270. entry >= dir->entries; entry--)
  271. entry->statDone = 0;
  272. SFdrawLists(SF_DO_SCROLL);
  273. }
  274. } else {
  275. XtVaSetValues(w, XtNlabel, "shown", NULL);
  276. for (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--)
  277. *(dir->dir) = 0; /* force a re-read */
  278. SFupdatePath();
  279. }
  280. }
  281. static void
  282. SFcreateWidgets(toplevel, prompt, ok, cancel)
  283. Widget toplevel;
  284. char *prompt;
  285. char *ok;
  286. char *cancel;
  287. {
  288. Cardinal i, n;
  289. int listWidth, listHeight;
  290. int listSpacing = 10;
  291. int scrollThickness = 15;
  292. int hScrollX, hScrollY;
  293. int vScrollX, vScrollY;
  294. Cursor
  295. xtermCursor,
  296. sbRightArrowCursor,
  297. dotCursor;
  298. Arg arglist[20];
  299. extern void SFinitFont (), SFcreateGC ();
  300. i = 0;
  301. XtSetArg(arglist[i], XtNtransientFor, toplevel); i++;
  302. selFile = XtAppCreateShell("selFile", "SelFile",
  303. transientShellWidgetClass, SFdisplay, arglist, i);
  304. /* Add WM_DELETE_WINDOW protocol */
  305. XtAppAddActions(XtWidgetToApplicationContext(selFile),
  306. actions, XtNumber(actions));
  307. XtOverrideTranslations(selFile,
  308. XtParseTranslationTable(wmDeleteWindowTranslation));
  309. i = 0;
  310. XtSetArg(arglist[i], XtNdefaultDistance, 30); i++;
  311. selFileForm = XtCreateManagedWidget("selFileForm",
  312. formWidgetClass, selFile, arglist, i);
  313. i = 0;
  314. XtSetArg(arglist[i], XtNlabel, prompt); i++;
  315. XtSetArg(arglist[i], XtNresizable, True); i++;
  316. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  317. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  318. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  319. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  320. XtSetArg(arglist[i], XtNborderWidth, 0); i++;
  321. selFilePrompt = XtCreateManagedWidget("selFilePrompt",
  322. labelWidgetClass, selFileForm, arglist, i);
  323. i = 0;
  324. XtSetArg(arglist[i], XtNforeground, &SFfore); i++;
  325. XtSetArg(arglist[i], XtNbackground, &SFback); i++;
  326. XtGetValues(selFilePrompt, arglist, i);
  327. SFinitFont();
  328. SFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth +
  329. SFbesideText;
  330. SFentryHeight = SFaboveAndBelowText + SFcharHeight +
  331. SFaboveAndBelowText;
  332. listWidth = SFlineToTextH + SFentryWidth + SFlineToTextH + 1 +
  333. scrollThickness;
  334. listHeight = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  335. SFlineToTextV + SFlistSize * SFentryHeight +
  336. SFlineToTextV + 1 + scrollThickness;
  337. SFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4;
  338. hScrollX = -1;
  339. hScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  340. SFlineToTextV + SFlistSize * SFentryHeight +
  341. SFlineToTextV;
  342. SFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH;
  343. vScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH;
  344. vScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV;
  345. SFvScrollHeight = SFlineToTextV + SFlistSize * SFentryHeight +
  346. SFlineToTextV;
  347. SFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1;
  348. SFlowerY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  349. SFlineToTextV;
  350. SFupperY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  351. SFlineToTextV + SFlistSize * SFentryHeight - 1;
  352. SFtextX = SFlineToTextH + SFbesideText;
  353. SFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent;
  354. SFsegs[0].x1 = 0;
  355. SFsegs[0].y1 = vScrollY;
  356. SFsegs[0].x2 = vScrollX - 1;
  357. SFsegs[0].y2 = vScrollY;
  358. SFsegs[1].x1 = vScrollX;
  359. SFsegs[1].y1 = 0;
  360. SFsegs[1].x2 = vScrollX;
  361. SFsegs[1].y2 = vScrollY - 1;
  362. SFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH;
  363. SFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 =
  364. SFlineToTextH + SFentryWidth - 1;
  365. i = 0;
  366. XtSetArg(arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4);
  367. i++;
  368. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  369. XtSetArg(arglist[i], XtNfromVert, selFilePrompt); i++;
  370. XtSetArg(arglist[i], XtNvertDistance, 10); i++;
  371. XtSetArg(arglist[i], XtNresizable, True); i++;
  372. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  373. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  374. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  375. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  376. XtSetArg(arglist[i], XtNstring, SFtextBuffer); i++;
  377. XtSetArg(arglist[i], XtNlength, MAXPATHLEN); i++;
  378. XtSetArg(arglist[i], XtNeditType, XawtextEdit); i++;
  379. XtSetArg(arglist[i], XtNwrap, XawtextWrapWord); i++;
  380. XtSetArg(arglist[i], XtNresize, XawtextResizeHeight); i++;
  381. XtSetArg(arglist[i], XtNuseStringInPlace, True); i++;
  382. selFileField = XtCreateManagedWidget("selFileField",
  383. asciiTextWidgetClass, selFileForm, arglist, i);
  384. XtOverrideTranslations(selFileField,
  385. XtParseTranslationTable(oneLineTextEditTranslations));
  386. /* XtSetKeyboardFocus(selFileForm, selFileField);
  387. need focus for selFileMask wigget to set the filter */
  388. i = 0;
  389. XtSetArg(arglist[i], XtNorientation, XtorientHorizontal); i++;
  390. XtSetArg(arglist[i], XtNwidth, SFpathScrollWidth); i++;
  391. XtSetArg(arglist[i], XtNheight, scrollThickness); i++;
  392. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  393. XtSetArg(arglist[i], XtNfromVert, selFileField); i++;
  394. XtSetArg(arglist[i], XtNvertDistance, 30); i++;
  395. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  396. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  397. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  398. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  399. selFileHScroll = XtCreateManagedWidget("selFileHScroll",
  400. scrollbarWidgetClass, selFileForm, arglist, i);
  401. XtAddCallback(selFileHScroll, XtNjumpProc,
  402. SFpathSliderMovedCallback, (XtPointer) NULL);
  403. XtAddCallback(selFileHScroll, XtNscrollProc,
  404. SFpathAreaSelectedCallback, (XtPointer) NULL);
  405. i = 0;
  406. XtSetArg(arglist[i], XtNwidth, listWidth); i++;
  407. XtSetArg(arglist[i], XtNheight, listHeight); i++;
  408. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  409. XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
  410. XtSetArg(arglist[i], XtNvertDistance, 10); i++;
  411. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  412. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  413. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  414. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  415. selFileLists[0] = XtCreateManagedWidget("selFileList1",
  416. compositeWidgetClass, selFileForm, arglist, i);
  417. i = 0;
  418. XtSetArg(arglist[i], XtNwidth, listWidth); i++;
  419. XtSetArg(arglist[i], XtNheight, listHeight); i++;
  420. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  421. XtSetArg(arglist[i], XtNfromHoriz, selFileLists[0]); i++;
  422. XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
  423. XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++;
  424. XtSetArg(arglist[i], XtNvertDistance, 10); i++;
  425. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  426. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  427. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  428. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  429. selFileLists[1] = XtCreateManagedWidget("selFileList2",
  430. compositeWidgetClass, selFileForm, arglist, i);
  431. i = 0;
  432. XtSetArg(arglist[i], XtNwidth, listWidth); i++;
  433. XtSetArg(arglist[i], XtNheight, listHeight); i++;
  434. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  435. XtSetArg(arglist[i], XtNfromHoriz, selFileLists[1]); i++;
  436. XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
  437. XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++;
  438. XtSetArg(arglist[i], XtNvertDistance, 10); i++;
  439. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  440. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  441. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  442. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  443. selFileLists[2] = XtCreateManagedWidget("selFileList3",
  444. compositeWidgetClass, selFileForm, arglist, i);
  445. for (n = 0; n < 3; n++) {
  446. i = 0;
  447. XtSetArg(arglist[i], XtNx, vScrollX); i++;
  448. XtSetArg(arglist[i], XtNy, vScrollY); i++;
  449. XtSetArg(arglist[i], XtNwidth, scrollThickness); i++;
  450. XtSetArg(arglist[i], XtNheight, SFvScrollHeight); i++;
  451. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  452. selFileVScrolls[n] = XtCreateManagedWidget("selFileVScroll",
  453. scrollbarWidgetClass, selFileLists[n], arglist, i);
  454. XtAddCallback(selFileVScrolls[n], XtNjumpProc,
  455. SFvFloatSliderMovedCallback, (XtPointer) n);
  456. XtAddCallback(selFileVScrolls[n], XtNscrollProc,
  457. SFvAreaSelectedCallback, (XtPointer) n);
  458. i = 0;
  459. XtSetArg(arglist[i], XtNorientation, XtorientHorizontal);
  460. i++;
  461. XtSetArg(arglist[i], XtNx, hScrollX); i++;
  462. XtSetArg(arglist[i], XtNy, hScrollY); i++;
  463. XtSetArg(arglist[i], XtNwidth, SFhScrollWidth); i++;
  464. XtSetArg(arglist[i], XtNheight, scrollThickness); i++;
  465. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  466. selFileHScrolls[n] = XtCreateManagedWidget("selFileHScroll",
  467. scrollbarWidgetClass, selFileLists[n], arglist, i);
  468. XtAddCallback(selFileHScrolls[n], XtNjumpProc,
  469. SFhSliderMovedCallback, (XtPointer) n);
  470. XtAddCallback(selFileHScrolls[n], XtNscrollProc,
  471. SFhAreaSelectedCallback, (XtPointer) n);
  472. }
  473. i = 0;
  474. XtSetArg(arglist[i], XtNlabel, ok); i++;
  475. XtSetArg(arglist[i], XtNresizable, True); i++;
  476. XtSetArg(arglist[i], XtNcallback, SFokSelect); i++;
  477. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  478. XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++;
  479. XtSetArg(arglist[i], XtNvertDistance, 30); i++;
  480. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  481. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  482. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  483. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  484. selFileOK = XtCreateManagedWidget("selFileOK", commandWidgetClass,
  485. selFileForm, arglist, i);
  486. i = 0;
  487. XtSetArg(arglist[i], XtNlabel, cancel); i++;
  488. XtSetArg(arglist[i], XtNresizable, True); i++;
  489. XtSetArg(arglist[i], XtNcallback, SFcancelSelect); i++;
  490. XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
  491. XtSetArg(arglist[i], XtNfromHoriz, selFileOK); i++;
  492. XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++;
  493. XtSetArg(arglist[i], XtNhorizDistance, 30); i++;
  494. XtSetArg(arglist[i], XtNvertDistance, 30); i++;
  495. XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
  496. XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
  497. XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
  498. XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
  499. selFileCancel = XtCreateManagedWidget("selFileCancel",
  500. commandWidgetClass, selFileForm, arglist, i);
  501. /* Do the file filter stuff. */
  502. selFileLabel = XtVaCreateManagedWidget("selFileLabel",
  503. labelWidgetClass, selFileForm,
  504. XtNfromVert, selFileLists[0],
  505. XtNvertDistance, 30,
  506. XtNfromHoriz, selFileCancel,
  507. XtNhorizDistance, 60,
  508. XtNlabel, "File Mask:",
  509. XtNborderWidth, 0,
  510. XtNtop, XtChainTop,
  511. XtNbottom, XtChainTop,
  512. NULL);
  513. selFileMask = XtVaCreateManagedWidget("selFileMask",
  514. asciiTextWidgetClass, selFileForm,
  515. XtNwidth, MASKWIDTH*SFcharWidth,
  516. XtNfromVert, selFileLists[0],
  517. XtNvertDistance, 30,
  518. XtNfromHoriz, selFileLabel,
  519. XtNhorizDistance, 0,
  520. XtNtop, XtChainTop,
  521. XtNbottom, XtChainTop,
  522. XtNstring, fileMask,
  523. XtNlength, sizeof(fileMask),
  524. XtNeditType, XawtextEdit,
  525. XtNwrap, XawtextWrapNever,
  526. XtNuseStringInPlace, True,
  527. NULL);
  528. for (i = 0; i < 3; i++)
  529. XtSetKeyboardFocus(selFileLists[i], selFileField);
  530. XtOverrideTranslations(selFileMask,
  531. XtParseTranslationTable(oneLineTextEditTranslations));
  532. XtAddEventHandler(selFileMask, KeyPressMask, False,
  533. maskChanged, (XtPointer) NULL);
  534. selFileLabel = XtVaCreateManagedWidget("selFileLabel",
  535. labelWidgetClass, selFileForm,
  536. XtNfromVert, selFileLists[0],
  537. XtNvertDistance, 30,
  538. XtNfromHoriz, selFileMask,
  539. XtNhorizDistance, 40,
  540. XtNlabel, "dot files",
  541. XtNborderWidth, 0,
  542. XtNtop, XtChainTop,
  543. XtNbottom, XtChainTop,
  544. NULL);
  545. selFileHide = XtVaCreateManagedWidget("selFileHide",
  546. commandWidgetClass, selFileForm,
  547. XtNfromVert, selFileLists[0],
  548. XtNvertDistance, 30,
  549. XtNfromHoriz, selFileLabel,
  550. XtNhorizDistance, 2,
  551. XtNlabel, "hidden",
  552. XtNborderWidth, 0,
  553. XtNtop, XtChainTop,
  554. XtNbottom, XtChainTop,
  555. #if 0 /* missing in R4, says
  556. pete@lovelace.thi.informatik.uni-frankfurt.de (Peter Dyballa) */
  557. XtNcursorName, "dot",
  558. #endif
  559. NULL);
  560. XtAddCallback(selFileHide, XtNcallback, hideFiles, NULL);
  561. XtSetMappedWhenManaged(selFile, False);
  562. XtRealizeWidget(selFile);
  563. /* Add WM_DELETE_WINDOW protocol */
  564. SFwmDeleteWindow = XInternAtom(SFdisplay, "WM_DELETE_WINDOW", False);
  565. XSetWMProtocols(SFdisplay, XtWindow(selFile), &SFwmDeleteWindow, 1);
  566. SFcreateGC();
  567. xtermCursor = XCreateFontCursor(SFdisplay, XC_xterm);
  568. sbRightArrowCursor = XCreateFontCursor(SFdisplay, XC_sb_right_arrow);
  569. dotCursor = XCreateFontCursor(SFdisplay, XC_dot);
  570. XDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor);
  571. XDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor);
  572. for (n = 0; n < 3; n++) {
  573. XDefineCursor(SFdisplay, XtWindow(selFileLists[n]),
  574. sbRightArrowCursor);
  575. }
  576. XDefineCursor(SFdisplay, XtWindow(selFileOK), dotCursor);
  577. XDefineCursor(SFdisplay, XtWindow(selFileCancel), dotCursor);
  578. for (n = 0; n < 3; n++) {
  579. XtAddEventHandler(selFileLists[n], ExposureMask, True,
  580. SFexposeList, (XtPointer) n);
  581. XtAddEventHandler(selFileLists[n], EnterWindowMask, False,
  582. SFenterList, (XtPointer) n);
  583. XtAddEventHandler(selFileLists[n], LeaveWindowMask, False,
  584. SFleaveList, (XtPointer) n);
  585. XtAddEventHandler(selFileLists[n], PointerMotionMask, False,
  586. SFmotionList, (XtPointer) n);
  587. XtAddEventHandler(selFileLists[n], ButtonPressMask, False,
  588. SFbuttonPressList, (XtPointer) n);
  589. XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False,
  590. SFbuttonReleaseList, (XtPointer) n);
  591. }
  592. XtAddEventHandler(selFileField, KeyPressMask, False,
  593. SFmodVerifyCallback, (XtPointer) NULL);
  594. SFapp = XtWidgetToApplicationContext(selFile);
  595. }
  596. /* position widget under the cursor */
  597. void
  598. SFpositionWidget(w)
  599. Widget w;
  600. {
  601. Arg args[3];
  602. Cardinal num_args;
  603. Dimension width, height, b_width;
  604. int x, y, max_x, max_y;
  605. Window root, child;
  606. int dummyx, dummyy;
  607. unsigned int dummymask;
  608. XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
  609. &dummyx, &dummyy, &dummymask);
  610. num_args = 0;
  611. XtSetArg(args[num_args], XtNwidth, &width); num_args++;
  612. XtSetArg(args[num_args], XtNheight, &height); num_args++;
  613. XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
  614. XtGetValues(w, args, num_args);
  615. width += 2 * b_width;
  616. height += 2 * b_width;
  617. x -= ( (Position) width/2 );
  618. if (x < 0) x = 0;
  619. if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
  620. y -= ( (Position) height/2 );
  621. if (y < 0) y = 0;
  622. if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
  623. num_args = 0;
  624. XtSetArg(args[num_args], XtNx, x); num_args++;
  625. XtSetArg(args[num_args], XtNy, y); num_args++;
  626. XtSetValues(w, args, num_args);
  627. }
  628. FILE *
  629. SFopenFile(name, mode, prompt, failed)
  630. char *name;
  631. char *mode;
  632. char *prompt;
  633. char *failed;
  634. {
  635. Arg args[1];
  636. FILE *fp;
  637. SFchdir(SFstartDir);
  638. errno = 0;
  639. if (!name || *name == 0 || (fp = fopen(name, mode)) == NULL) {
  640. char *buf;
  641. char *msg = errno ? strerror (errno) : "";
  642. buf = XtMalloc(strlen (failed) + strlen (msg) + strlen (prompt) + 2);
  643. strcpy(buf, failed);
  644. strcat(buf, msg);
  645. strcat(buf, " ");
  646. strcat(buf, prompt);
  647. XtSetArg(args[0], XtNlabel, buf);
  648. XtSetValues(selFilePrompt, args, ONE);
  649. XtFree(buf);
  650. fp = NULL;
  651. }
  652. return fp;
  653. }
  654. void
  655. SFtextChanged()
  656. {
  657. extern void SFupdatePath ();
  658. if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
  659. (void) strcpy(SFcurrentPath, SFtextBuffer);
  660. SFtextPos = XawTextGetInsertionPoint(selFileField);
  661. } else {
  662. (void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer);
  663. SFtextPos = XawTextGetInsertionPoint(selFileField) +
  664. strlen(SFstartDir);
  665. }
  666. if (!SFworkProcAdded) {
  667. (void) XtAppAddWorkProc(SFapp, SFworkProc, NULL);
  668. SFworkProcAdded = 1;
  669. }
  670. SFupdatePath();
  671. }
  672. static char *
  673. SFgetText()
  674. {
  675. return strcpy(XtMalloc((unsigned) (strlen(SFtextBuffer) + 1)),
  676. SFtextBuffer);
  677. }
  678. static void
  679. SFprepareToReturn()
  680. {
  681. SFstatus = SEL_FILE_NULL;
  682. XtRemoveGrab(selFile);
  683. XtUnmapWidget(selFile);
  684. XtRemoveTimeOut(SFdirModTimerId);
  685. if (SFchdir(SFstartDir)) {
  686. XtAppError(
  687. SFapp,
  688. "XsraSelFile: can't return to current directory"
  689. );
  690. }
  691. }
  692. FILE *
  693. XsraSelFile(toplevel, prompt, ok, cancel, failed,
  694. init_path, mode, show_entry, name_return)
  695. Widget toplevel;
  696. char *prompt;
  697. char *ok;
  698. char *cancel;
  699. char *failed;
  700. char *init_path;
  701. char *mode;
  702. int (*show_entry)();
  703. char **name_return;
  704. {
  705. extern void SFsetText ();
  706. static int firstTime = 1;
  707. Cardinal i;
  708. Arg arglist[20];
  709. XEvent event;
  710. FILE *fp;
  711. if (!prompt) {
  712. prompt = "Pathname:";
  713. }
  714. if (!ok) {
  715. ok = "OK";
  716. }
  717. if (!cancel) {
  718. cancel = "Cancel";
  719. }
  720. if (firstTime) {
  721. firstTime = 0;
  722. SFdisplay = XtDisplay(toplevel);
  723. SFcreateWidgets(toplevel, prompt, ok, cancel);
  724. } else {
  725. i = 0;
  726. XtSetArg(arglist[i], XtNlabel, prompt); i++;
  727. XtSetValues(selFilePrompt, arglist, i);
  728. i = 0;
  729. XtSetArg(arglist[i], XtNlabel, ok); i++;
  730. XtSetValues(selFileOK, arglist, i);
  731. i = 0;
  732. XtSetArg(arglist[i], XtNlabel, cancel); i++;
  733. XtSetValues(selFileCancel, arglist, i);
  734. }
  735. SFpositionWidget(selFile);
  736. XtMapWidget(selFile);
  737. {
  738. char *cwd = xgetcwd ();
  739. strcpy (SFstartDir, cwd);
  740. free (cwd);
  741. }
  742. if (SFstartDir[0] == 0) {
  743. XtAppError(SFapp, "XsraSelFile: can't get current directory");
  744. }
  745. (void) strcat(SFstartDir, "/");
  746. (void) strcpy(SFcurrentDir, SFstartDir);
  747. if (init_path) {
  748. if (init_path[0] == '/') {
  749. (void) strcpy(SFcurrentPath, init_path);
  750. if (strncmp(
  751. SFcurrentPath,
  752. SFstartDir,
  753. strlen(SFstartDir)
  754. )) {
  755. SFsetText(SFcurrentPath);
  756. } else {
  757. SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
  758. }
  759. } else {
  760. (void) strcat(strcpy(SFcurrentPath, SFstartDir),
  761. init_path);
  762. SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
  763. }
  764. } else {
  765. (void) strcpy(SFcurrentPath, SFstartDir);
  766. }
  767. /* SFfunc = show_entry;
  768. disabled in order to implement file filter */
  769. SFfunc = showEntry;
  770. SFtextChanged();
  771. XtAddGrab(selFile, True, True);
  772. SFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000,
  773. SFdirModTimer, (XtPointer) NULL);
  774. while (1) {
  775. XtAppNextEvent(SFapp, &event);
  776. XtDispatchEvent(&event);
  777. switch (SFstatus) {
  778. case SEL_FILE_TEXT:
  779. SFstatus = SEL_FILE_NULL;
  780. SFtextChanged();
  781. break;
  782. case SEL_FILE_OK:
  783. *name_return = SFgetText();
  784. if ((fp = SFopenFile(*name_return, mode,
  785. prompt, failed))) {
  786. SFprepareToReturn();
  787. return fp;
  788. }
  789. SFstatus = SEL_FILE_NULL;
  790. break;
  791. case SEL_FILE_CANCEL:
  792. SFprepareToReturn();
  793. return NULL;
  794. case SEL_FILE_NULL:
  795. break;
  796. }
  797. }
  798. }
  799. #endif /* not NOSELFILE and not NOTOOL */