PageRenderTime 70ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/graphviz-2.28.0/cmd/lefty/ws/x11/libfilereq/SelFile.c

#
C | 782 lines | 612 code | 115 blank | 55 comment | 49 complexity | d71f7116b4148d88628a428272889507 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0, CPL-1.0, BSD-3-Clause, LGPL-2.1
  1. /* $Id: SelFile.c,v 1.9 2011/01/25 16:30:46 ellson Exp $ $Revision: 1.9 $ */
  2. /* vim:set shiftwidth=4 ts=8: */
  3. /*************************************************************************
  4. * Copyright (c) 2011 AT&T Intellectual Property
  5. * All rights reserved. This program and the accompanying materials
  6. * are made available under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution, and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors: See CVS logs. Details at http://www.graphviz.org/
  11. *************************************************************************/
  12. #ifdef FEATURE_CS
  13. #include <ast.h>
  14. #endif
  15. /*
  16. * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
  17. *
  18. * Permission to use, copy, modify, and distribute this software and its
  19. * documentation for any purpose and without fee is hereby granted, provided
  20. * that the above copyright notice appear in all copies and that both that
  21. * copyright notice and this permission notice appear in supporting
  22. * documentation, and that the name of Software Research Associates not be used
  23. * in advertising or publicity pertaining to distribution of the software
  24. * without specific, written prior permission. Software Research Associates
  25. * makes no representations about the suitability of this software for any
  26. * purpose. It is provided "as is" without express or implied warranty.
  27. *
  28. * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  29. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  30. * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
  31. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  32. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  33. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  34. * PERFORMANCE OF THIS SOFTWARE.
  35. *
  36. * Author: Erik M. van der Poel
  37. * Software Research Associates, Inc., Tokyo, Japan
  38. * erik@sra.co.jp
  39. */
  40. /*
  41. * Author's address:
  42. *
  43. * erik@sra.co.jp
  44. * OR
  45. * erik%sra.co.jp@uunet.uu.net
  46. * OR
  47. * erik%sra.co.jp@mcvax.uucp
  48. * OR
  49. * try junet instead of co.jp
  50. * OR
  51. * Erik M. van der Poel
  52. * Software Research Associates, Inc.
  53. * 1-1-1 Hirakawa-cho, Chiyoda-ku
  54. * Tokyo 102 Japan. TEL +81-3-234-2692
  55. */
  56. #ifdef HAVE_CONFIG_H
  57. #include "config.h"
  58. #endif
  59. #include <stdio.h>
  60. #ifdef HAVE_ERRNO_H
  61. #include <errno.h>
  62. #endif
  63. #ifndef HAVE_STRERROR
  64. # ifndef HAVE_ERRNO_DECL
  65. extern int errno;
  66. extern int sys_nerr;
  67. # if (linux)
  68. extern const char *const sys_errlist[];
  69. # else
  70. extern char *sys_errlist[];
  71. # endif
  72. # endif
  73. #endif
  74. #include <sys/param.h>
  75. #include <X11/cursorfont.h>
  76. #include <X11/Intrinsic.h>
  77. #include <X11/StringDefs.h>
  78. #include <X11/Composite.h>
  79. #include <X11/Shell.h>
  80. #include <X11/Xaw/Form.h>
  81. #include <X11/Xaw/Command.h>
  82. #include <X11/Xaw/Scrollbar.h>
  83. #include <X11/Xaw/Label.h>
  84. #include <X11/Xaw/Cardinals.h>
  85. #include "SFinternal.h"
  86. #ifndef MAXPATHLEN
  87. #define MAXPATHLEN 1024
  88. #endif /* ndef MAXPATHLEN */
  89. #include "SFDecls.h"
  90. #if !defined (SVR4) && !defined (SYSV) && !defined (USG)
  91. extern char *getwd (char *);
  92. #endif /* !defined (SVR4) && !defined (SYSV) && !defined (USG) */
  93. #ifdef HAVE_STDLIB_H
  94. # include <stdlib.h>
  95. #endif
  96. #ifdef HAVE_STDINT_H
  97. #include <stdint.h>
  98. #endif
  99. #ifdef HAVE_INTTYPES_H
  100. #include <inttypes.h>
  101. #endif
  102. #ifdef HAVE_INTPTR_T
  103. #define INT2PTR(t,v) ((t)(intptr_t)(v))
  104. #define PTR2INT(v) ((Sflong_t)(intptr_t)(v))
  105. #else
  106. #define INT2PTR(t,v) ((t)(v))
  107. #define PTR2INT(v) ((Sflong_t)(v))
  108. #endif
  109. int SFstatus = SEL_FILE_NULL;
  110. char SFstartDir[MAXPATHLEN], SFcurrentPath[MAXPATHLEN];
  111. char SFcurrentDir[MAXPATHLEN];
  112. Widget selFile, selFileCancel, selFileField, selFileForm, selFileHScroll;
  113. Widget selFileHScrolls[3], selFileLists[3], selFileOK, selFilePrompt;
  114. Widget selFileVScrolls[3];
  115. Display *SFdisplay;
  116. Pixel SFfore, SFback;
  117. Atom SFwmDeleteWindow;
  118. XSegment SFsegs[2], SFcompletionSegs[2];
  119. XawTextPosition SFtextPos;
  120. int SFupperX, SFlowerY, SFupperY;
  121. int SFtextX, SFtextYoffset;
  122. int SFentryWidth, SFentryHeight;
  123. int SFlineToTextH = 3;
  124. int SFlineToTextV = 3;
  125. int SFbesideText = 3;
  126. int SFaboveAndBelowText = 2;
  127. int SFcharsPerEntry = 15;
  128. int SFlistSize = 10;
  129. int SFworkProcAdded = 0;
  130. XtWorkProcId SFworkProcId;
  131. XtAppContext SFapp;
  132. int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
  133. char SFtextBuffer[MAXPATHLEN];
  134. XtIntervalId SFdirModTimerId;
  135. int (*SFfunc) (char *, char **, struct stat *);
  136. static char *oneLineTextEditTranslations = "\
  137. <Key>Return: redraw-display()\n\
  138. Ctrl<Key>M: redraw-display()\n\
  139. ";
  140. static void SFexposeList (Widget w, XtPointer n, XEvent *event, Boolean *cont) {
  141. if ((event->type == NoExpose) || event->xexpose.count) {
  142. return;
  143. }
  144. SFdrawList ((intptr_t) n, SF_DO_NOT_SCROLL);
  145. }
  146. static void SFmodVerifyCallback (
  147. Widget w, XtPointer client_data, XEvent *event, Boolean *cont
  148. ) {
  149. char buf[2];
  150. if (
  151. XLookupString (&event->xkey, buf, 2, NULL, NULL) == 1 && *buf == '\r'
  152. ) {
  153. SFstatus = SEL_FILE_OK;
  154. } else {
  155. SFstatus = SEL_FILE_TEXT;
  156. }
  157. }
  158. static void SFokCallback (Widget w, XtPointer cl, XtPointer cd) {
  159. SFstatus = SEL_FILE_OK;
  160. }
  161. static XtCallbackRec SFokSelect[] = {
  162. { SFokCallback, (XtPointer) NULL },
  163. { NULL, (XtPointer) NULL },
  164. };
  165. static void SFcancelCallback (Widget w, XtPointer cl, XtPointer cd) {
  166. SFstatus = SEL_FILE_CANCEL;
  167. }
  168. static XtCallbackRec SFcancelSelect[] = {
  169. { SFcancelCallback, (XtPointer) NULL },
  170. { NULL, (XtPointer) NULL },
  171. };
  172. static void SFdismissAction (
  173. Widget w, XEvent *event, String *params, Cardinal *num_params
  174. ) {
  175. if (
  176. event->type == ClientMessage &&
  177. event->xclient.data.l[0] != SFwmDeleteWindow
  178. )
  179. return;
  180. SFstatus = SEL_FILE_CANCEL;
  181. }
  182. static char *wmDeleteWindowTranslation = "\
  183. <Message>WM_PROTOCOLS: SelFileDismiss()\n\
  184. ";
  185. static XtActionsRec actions[] = {
  186. { "SelFileDismiss", SFdismissAction },
  187. };
  188. static void SFcreateWidgets (
  189. Widget toplevel, char *prompt, char *ok, char *cancel
  190. ) {
  191. Cardinal i;
  192. intptr_t n;
  193. int listWidth, listHeight;
  194. int listSpacing = 10;
  195. int scrollThickness = 15;
  196. int hScrollX, hScrollY;
  197. int vScrollX, vScrollY;
  198. Cursor xtermCursor, sbRightArrowCursor, dotCursor;
  199. Arg arglist[20];
  200. i = 0;
  201. XtSetArg (arglist[i], XtNtransientFor, toplevel); i++;
  202. selFile = XtAppCreateShell (
  203. "selFile", "SelFile", transientShellWidgetClass, SFdisplay, arglist, i
  204. );
  205. /* Add WM_DELETE_WINDOW protocol */
  206. XtAppAddActions (
  207. XtWidgetToApplicationContext (selFile), actions, XtNumber (actions)
  208. );
  209. XtOverrideTranslations (
  210. selFile, XtParseTranslationTable (wmDeleteWindowTranslation)
  211. );
  212. i = 0;
  213. XtSetArg (arglist[i], XtNdefaultDistance, 30); i++;
  214. selFileForm = XtCreateManagedWidget (
  215. "selFileForm", formWidgetClass, selFile, arglist, i
  216. );
  217. i = 0;
  218. XtSetArg (arglist[i], XtNlabel, prompt); i++;
  219. XtSetArg (arglist[i], XtNresizable, True); i++;
  220. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  221. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  222. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  223. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  224. XtSetArg (arglist[i], XtNborderWidth, 0); i++;
  225. selFilePrompt = XtCreateManagedWidget (
  226. "selFilePrompt", labelWidgetClass, selFileForm, arglist, i
  227. );
  228. i = 0;
  229. XtSetArg (arglist[i], XtNforeground, &SFfore); i++;
  230. XtSetArg (arglist[i], XtNbackground, &SFback); i++;
  231. XtGetValues (selFilePrompt, arglist, i);
  232. SFinitFont ();
  233. SFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth + SFbesideText;
  234. SFentryHeight = SFaboveAndBelowText + SFcharHeight + SFaboveAndBelowText;
  235. listWidth = (
  236. SFlineToTextH + SFentryWidth + SFlineToTextH + 1 + scrollThickness
  237. );
  238. listHeight = (
  239. SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  240. SFlineToTextV + SFlistSize * SFentryHeight +
  241. SFlineToTextV + 1 + scrollThickness
  242. );
  243. SFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4;
  244. hScrollX = -1;
  245. hScrollY = (
  246. SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  247. SFlineToTextV + SFlistSize * SFentryHeight + SFlineToTextV
  248. );
  249. SFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH;
  250. vScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH;
  251. vScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV;
  252. SFvScrollHeight = (
  253. SFlineToTextV + SFlistSize * SFentryHeight + SFlineToTextV
  254. );
  255. SFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1;
  256. SFlowerY = (
  257. SFlineToTextV + SFentryHeight + SFlineToTextV + 1 + SFlineToTextV
  258. );
  259. SFupperY = (
  260. SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  261. SFlineToTextV + SFlistSize * SFentryHeight - 1
  262. );
  263. SFtextX = SFlineToTextH + SFbesideText;
  264. SFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent;
  265. SFsegs[0].x1 = 0;
  266. SFsegs[0].y1 = vScrollY;
  267. SFsegs[0].x2 = vScrollX - 1;
  268. SFsegs[0].y2 = vScrollY;
  269. SFsegs[1].x1 = vScrollX;
  270. SFsegs[1].y1 = 0;
  271. SFsegs[1].x2 = vScrollX;
  272. SFsegs[1].y2 = vScrollY - 1;
  273. SFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH;
  274. SFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 = (
  275. SFlineToTextH + SFentryWidth - 1
  276. );
  277. i = 0;
  278. XtSetArg (arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4); i++;
  279. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  280. XtSetArg (arglist[i], XtNfromVert, selFilePrompt); i++;
  281. XtSetArg (arglist[i], XtNvertDistance, 10); i++;
  282. XtSetArg (arglist[i], XtNresizable, True); i++;
  283. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  284. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  285. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  286. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  287. XtSetArg (arglist[i], XtNstring, SFtextBuffer); i++;
  288. XtSetArg (arglist[i], XtNlength, MAXPATHLEN); i++;
  289. XtSetArg (arglist[i], XtNeditType, XawtextEdit); i++;
  290. XtSetArg (arglist[i], XtNwrap, XawtextWrapWord); i++;
  291. XtSetArg (arglist[i], XtNresize, XawtextResizeHeight); i++;
  292. XtSetArg (arglist[i], XtNuseStringInPlace, True); i++;
  293. selFileField = XtCreateManagedWidget (
  294. "selFileField", asciiTextWidgetClass, selFileForm, arglist, i
  295. );
  296. XtOverrideTranslations (
  297. selFileField, XtParseTranslationTable (oneLineTextEditTranslations)
  298. );
  299. XtSetKeyboardFocus (selFileForm, selFileField);
  300. i = 0;
  301. XtSetArg (arglist[i], XtNorientation, XtorientHorizontal); i++;
  302. XtSetArg (arglist[i], XtNwidth, SFpathScrollWidth); i++;
  303. XtSetArg (arglist[i], XtNheight, scrollThickness); i++;
  304. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  305. XtSetArg (arglist[i], XtNfromVert, selFileField); i++;
  306. XtSetArg (arglist[i], XtNvertDistance, 30); i++;
  307. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  308. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  309. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  310. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  311. selFileHScroll = XtCreateManagedWidget (
  312. "selFileHScroll", scrollbarWidgetClass, selFileForm, arglist, i
  313. );
  314. XtAddCallback (
  315. selFileHScroll, XtNjumpProc, SFpathSliderMovedCallback, (XtPointer) NULL
  316. );
  317. XtAddCallback (
  318. selFileHScroll, XtNscrollProc, SFpathAreaSelectedCallback,
  319. (XtPointer) NULL
  320. );
  321. i = 0;
  322. XtSetArg (arglist[i], XtNwidth, listWidth); i++;
  323. XtSetArg (arglist[i], XtNheight, listHeight); i++;
  324. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  325. XtSetArg (arglist[i], XtNfromVert, selFileHScroll); i++;
  326. XtSetArg (arglist[i], XtNvertDistance, 10); i++;
  327. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  328. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  329. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  330. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  331. selFileLists[0] = XtCreateManagedWidget (
  332. "selFileList1", compositeWidgetClass, selFileForm, arglist, i
  333. );
  334. i = 0;
  335. XtSetArg (arglist[i], XtNwidth, listWidth); i++;
  336. XtSetArg (arglist[i], XtNheight, listHeight); i++;
  337. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  338. XtSetArg (arglist[i], XtNfromHoriz, selFileLists[0]); i++;
  339. XtSetArg (arglist[i], XtNfromVert, selFileHScroll); i++;
  340. XtSetArg (arglist[i], XtNhorizDistance, listSpacing); i++;
  341. XtSetArg (arglist[i], XtNvertDistance, 10); i++;
  342. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  343. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  344. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  345. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  346. selFileLists[1] = XtCreateManagedWidget (
  347. "selFileList2", compositeWidgetClass, selFileForm, arglist, i
  348. );
  349. i = 0;
  350. XtSetArg (arglist[i], XtNwidth, listWidth); i++;
  351. XtSetArg (arglist[i], XtNheight, listHeight); i++;
  352. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  353. XtSetArg (arglist[i], XtNfromHoriz, selFileLists[1]); i++;
  354. XtSetArg (arglist[i], XtNfromVert, selFileHScroll); i++;
  355. XtSetArg (arglist[i], XtNhorizDistance, listSpacing); i++;
  356. XtSetArg (arglist[i], XtNvertDistance, 10); i++;
  357. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  358. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  359. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  360. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  361. selFileLists[2] = XtCreateManagedWidget (
  362. "selFileList3", compositeWidgetClass, selFileForm, arglist, i
  363. );
  364. for (n = 0; n < 3; n++) {
  365. i = 0;
  366. XtSetArg (arglist[i], XtNx, vScrollX); i++;
  367. XtSetArg (arglist[i], XtNy, vScrollY); i++;
  368. XtSetArg (arglist[i], XtNwidth, scrollThickness); i++;
  369. XtSetArg (arglist[i], XtNheight, SFvScrollHeight); i++;
  370. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  371. selFileVScrolls[n] = XtCreateManagedWidget (
  372. "selFileVScroll", scrollbarWidgetClass, selFileLists[n], arglist, i
  373. );
  374. XtAddCallback (
  375. selFileVScrolls[n], XtNjumpProc,
  376. SFvFloatSliderMovedCallback, (XtPointer) n
  377. );
  378. XtAddCallback (
  379. selFileVScrolls[n], XtNscrollProc,
  380. SFvAreaSelectedCallback, (XtPointer) n
  381. );
  382. i = 0;
  383. XtSetArg (arglist[i], XtNorientation, XtorientHorizontal); i++;
  384. XtSetArg (arglist[i], XtNx, hScrollX); i++;
  385. XtSetArg (arglist[i], XtNy, hScrollY); i++;
  386. XtSetArg (arglist[i], XtNwidth, SFhScrollWidth); i++;
  387. XtSetArg (arglist[i], XtNheight, scrollThickness); i++;
  388. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  389. selFileHScrolls[n] = XtCreateManagedWidget (
  390. "selFileHScroll", scrollbarWidgetClass, selFileLists[n], arglist, i
  391. );
  392. XtAddCallback (
  393. selFileHScrolls[n], XtNjumpProc,
  394. SFhSliderMovedCallback, (XtPointer) n
  395. );
  396. XtAddCallback (
  397. selFileHScrolls[n], XtNscrollProc,
  398. SFhAreaSelectedCallback, (XtPointer) n
  399. );
  400. }
  401. i = 0;
  402. XtSetArg (arglist[i], XtNlabel, ok); i++;
  403. XtSetArg (arglist[i], XtNresizable, True); i++;
  404. XtSetArg (arglist[i], XtNcallback, SFokSelect); i++;
  405. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  406. XtSetArg (arglist[i], XtNfromVert, selFileLists[0]); i++;
  407. XtSetArg (arglist[i], XtNvertDistance, 30); i++;
  408. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  409. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  410. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  411. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  412. selFileOK = XtCreateManagedWidget (
  413. "selFileOK", commandWidgetClass, selFileForm, arglist, i
  414. );
  415. i = 0;
  416. XtSetArg (arglist[i], XtNlabel, cancel); i++;
  417. XtSetArg (arglist[i], XtNresizable, True); i++;
  418. XtSetArg (arglist[i], XtNcallback, SFcancelSelect); i++;
  419. XtSetArg (arglist[i], XtNborderColor, SFfore); i++;
  420. XtSetArg (arglist[i], XtNfromHoriz, selFileOK); i++;
  421. XtSetArg (arglist[i], XtNfromVert, selFileLists[0]); i++;
  422. XtSetArg (arglist[i], XtNhorizDistance, 30); i++;
  423. XtSetArg (arglist[i], XtNvertDistance, 30); i++;
  424. XtSetArg (arglist[i], XtNtop, XtChainTop); i++;
  425. XtSetArg (arglist[i], XtNbottom, XtChainTop); i++;
  426. XtSetArg (arglist[i], XtNleft, XtChainLeft); i++;
  427. XtSetArg (arglist[i], XtNright, XtChainLeft); i++;
  428. selFileCancel = XtCreateManagedWidget (
  429. "selFileCancel", commandWidgetClass, selFileForm, arglist, i
  430. );
  431. XtSetMappedWhenManaged (selFile, False);
  432. XtRealizeWidget (selFile);
  433. /* Add WM_DELETE_WINDOW protocol */
  434. SFwmDeleteWindow = XInternAtom (SFdisplay, "WM_DELETE_WINDOW", False);
  435. XSetWMProtocols (SFdisplay, XtWindow (selFile), &SFwmDeleteWindow, 1);
  436. SFcreateGC ();
  437. xtermCursor = XCreateFontCursor (SFdisplay, XC_xterm);
  438. sbRightArrowCursor = XCreateFontCursor (SFdisplay, XC_sb_right_arrow);
  439. dotCursor = XCreateFontCursor (SFdisplay, XC_dot);
  440. XDefineCursor (SFdisplay, XtWindow (selFileForm), xtermCursor);
  441. XDefineCursor (SFdisplay, XtWindow (selFileField), xtermCursor);
  442. for (n = 0; n < 3; n++) {
  443. XDefineCursor (
  444. SFdisplay, XtWindow (selFileLists[n]), sbRightArrowCursor
  445. );
  446. }
  447. XDefineCursor (SFdisplay, XtWindow (selFileOK), dotCursor);
  448. XDefineCursor (SFdisplay, XtWindow (selFileCancel), dotCursor);
  449. for (n = 0; n < 3; n++) {
  450. XtAddEventHandler (
  451. selFileLists[n], ExposureMask, True,
  452. SFexposeList, (XtPointer) n
  453. );
  454. XtAddEventHandler (
  455. selFileLists[n], EnterWindowMask, False,
  456. SFenterList, (XtPointer) n
  457. );
  458. XtAddEventHandler (
  459. selFileLists[n], LeaveWindowMask, False,
  460. SFleaveList, (XtPointer) n
  461. );
  462. XtAddEventHandler (
  463. selFileLists[n], PointerMotionMask, False,
  464. SFmotionList, (XtPointer) n
  465. );
  466. XtAddEventHandler (
  467. selFileLists[n], ButtonPressMask, False,
  468. SFbuttonPressList, (XtPointer) n
  469. );
  470. XtAddEventHandler (
  471. selFileLists[n], ButtonReleaseMask, False,
  472. SFbuttonReleaseList, (XtPointer) n
  473. );
  474. }
  475. XtAddEventHandler (
  476. selFileField, KeyPressMask, False,
  477. SFmodVerifyCallback, (XtPointer) NULL
  478. );
  479. SFapp = XtWidgetToApplicationContext (selFile);
  480. }
  481. /* position widget under the cursor */
  482. static void SFpositionWidget (Widget w) {
  483. Arg args[3];
  484. Cardinal num_args;
  485. Dimension width, height, b_width;
  486. int x, y, max_x, max_y;
  487. Window root, child;
  488. int dummyx, dummyy;
  489. unsigned int dummymask;
  490. XQueryPointer (
  491. XtDisplay (w), XtWindow (w), &root, &child, &x, &y,
  492. &dummyx, &dummyy, &dummymask
  493. );
  494. num_args = 0;
  495. XtSetArg (args[num_args], XtNwidth, &width); num_args++;
  496. XtSetArg (args[num_args], XtNheight, &height); num_args++;
  497. XtSetArg (args[num_args], XtNborderWidth, &b_width); num_args++;
  498. XtGetValues (w, args, num_args);
  499. width += 2 * b_width;
  500. height += 2 * b_width;
  501. x -= ((Position) width / 2);
  502. if (x < 0)
  503. x = 0;
  504. if (x > (max_x = (Position) (XtScreen (w)->width - width)))
  505. x = max_x;
  506. y -= ((Position) height / 2);
  507. if (y < 0)
  508. y = 0;
  509. if (y > (max_y = (Position) (XtScreen (w)->height - height)))
  510. y = max_y;
  511. num_args = 0;
  512. XtSetArg (args[num_args], XtNx, x); num_args++;
  513. XtSetArg (args[num_args], XtNy, y); num_args++;
  514. XtSetValues (w, args, num_args);
  515. }
  516. FILE *SFopenFile (char *name, char *mode, char *prompt, char *failed) {
  517. Arg args[1];
  518. FILE *fp;
  519. SFchdir (SFstartDir);
  520. if ((fp = fopen (name, mode)) == NULL) {
  521. char *buf;
  522. #ifdef HAVE_STRERROR
  523. char *errormsg = strerror (errno);
  524. if (errormsg) {
  525. buf = XtMalloc (
  526. strlen (failed) + strlen (errormsg) + strlen (prompt) + 2
  527. );
  528. strcpy (buf, failed);
  529. strcat (buf, errormsg);
  530. strcat (buf, "\n");
  531. #else
  532. if (errno < sys_nerr) {
  533. buf = XtMalloc (
  534. strlen (failed) + strlen (sys_errlist[errno]) +
  535. strlen (prompt) + 2
  536. );
  537. strcpy (buf, failed);
  538. strcat (buf, sys_errlist[errno]);
  539. strcat (buf, "\n");
  540. strcat (buf, prompt);
  541. #endif
  542. } else {
  543. buf = XtMalloc (strlen (failed) + strlen (prompt) + 2);
  544. strcpy (buf, failed);
  545. strcat (buf, "\n");
  546. strcat (buf, prompt);
  547. }
  548. XtSetArg (args[0], XtNlabel, buf);
  549. XtSetValues (selFilePrompt, args, ONE);
  550. XtFree (buf);
  551. return NULL;
  552. }
  553. return fp;
  554. }
  555. void SFtextChanged (void) {
  556. if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
  557. strcpy (SFcurrentPath, SFtextBuffer);
  558. SFtextPos = XawTextGetInsertionPoint (selFileField);
  559. } else {
  560. strcat (strcpy (SFcurrentPath, SFstartDir), SFtextBuffer);
  561. SFtextPos = XawTextGetInsertionPoint (
  562. selFileField
  563. ) + strlen (SFstartDir);
  564. }
  565. if (!SFworkProcAdded) {
  566. SFworkProcId = XtAppAddWorkProc (SFapp, SFworkProc, NULL);
  567. SFworkProcAdded = 1;
  568. }
  569. SFupdatePath ();
  570. }
  571. static void SFprepareToReturn (void) {
  572. SFstatus = SEL_FILE_NULL;
  573. XtRemoveGrab (selFile);
  574. XtUnmapWidget (selFile);
  575. XtRemoveTimeOut (SFdirModTimerId);
  576. if (SFchdir (SFstartDir)) {
  577. XtAppError (SFapp, "XsraSelFile: can't return to current directory");
  578. }
  579. }
  580. int
  581. XsraSelFile (
  582. Widget toplevel, char *prompt, char *ok, char *cancel, char *failed,
  583. char *init_path, char *mode,
  584. int (*show_entry) (char *, char **, struct stat *),
  585. char *name_return, int name_size
  586. ) {
  587. static int firstTime = 1;
  588. Cardinal i;
  589. Arg arglist[20];
  590. XEvent event;
  591. if (!prompt) {
  592. prompt = "Pathname:";
  593. }
  594. if (!ok) {
  595. ok = "OK";
  596. }
  597. if (!cancel) {
  598. cancel = "Cancel";
  599. }
  600. if (firstTime) {
  601. firstTime = 0;
  602. SFdisplay = XtDisplay (toplevel);
  603. SFcreateWidgets (toplevel, prompt, ok, cancel);
  604. } else {
  605. i = 0;
  606. XtSetArg (arglist[i], XtNlabel, prompt); i++;
  607. XtSetValues (selFilePrompt, arglist, i);
  608. i = 0;
  609. XtSetArg (arglist[i], XtNlabel, ok); i++;
  610. XtSetValues (selFileOK, arglist, i);
  611. i = 0;
  612. XtSetArg (arglist[i], XtNlabel, cancel); i++;
  613. XtSetValues (selFileCancel, arglist, i);
  614. }
  615. SFpositionWidget (selFile);
  616. XtMapWidget (selFile);
  617. if (!getcwd (SFstartDir, MAXPATHLEN)) {
  618. XtAppError (SFapp, "XsraSelFile: can't get current directory");
  619. }
  620. strcat (SFstartDir, "/");
  621. strcpy (SFcurrentDir, SFstartDir);
  622. if (init_path) {
  623. if (init_path[0] == '/') {
  624. strcpy (SFcurrentPath, init_path);
  625. if (strncmp (SFcurrentPath, SFstartDir, strlen (SFstartDir))) {
  626. SFsetText (SFcurrentPath);
  627. } else {
  628. SFsetText (& (SFcurrentPath[strlen (SFstartDir)]));
  629. }
  630. } else {
  631. strcat (strcpy (SFcurrentPath, SFstartDir), init_path);
  632. SFsetText (& (SFcurrentPath[strlen (SFstartDir)]));
  633. }
  634. } else {
  635. strcpy (SFcurrentPath, SFstartDir);
  636. }
  637. SFfunc = show_entry;
  638. SFtextChanged ();
  639. XtAddGrab (selFile, True, True);
  640. SFdirModTimerId = XtAppAddTimeOut (
  641. SFapp, (unsigned long) 1000, SFdirModTimer, (XtPointer) NULL
  642. );
  643. while (1) {
  644. XtAppNextEvent (SFapp, &event);
  645. XtDispatchEvent (&event);
  646. switch (SFstatus) {
  647. case SEL_FILE_TEXT:
  648. SFstatus = SEL_FILE_NULL;
  649. SFtextChanged ();
  650. break;
  651. case SEL_FILE_OK:
  652. strncpy (name_return, SFtextBuffer, name_size);
  653. SFprepareToReturn ();
  654. if (SFworkProcAdded) {
  655. XtRemoveWorkProc (SFworkProcId);
  656. SFworkProcAdded = 0;
  657. }
  658. return 1;
  659. case SEL_FILE_CANCEL:
  660. SFprepareToReturn ();
  661. return 0;
  662. case SEL_FILE_NULL:
  663. break;
  664. }
  665. }
  666. return 0;
  667. }