"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
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
27 /*
28 * Author's address:
29 *
30 * erik@sra.co.jp
31 * OR
32 * erik%sra.co.jp@uunet.uu.net
33 * OR
34 * erik%sra.co.jp@mcvax.uucp
35 * OR
36 * try junet instead of co.jp
37 * OR
38 * Erik M. van der Poel
39 * Software Research Associates, Inc.
40 * 1-1-1 Hirakawa-cho, Chiyoda-ku
41 * Tokyo 102 Japan. TEL +81-3-234-2692
42 */
43
44 #include <stdio.h>
45 #include <errno.h>
46 /* BSD 4.3 errno.h does not declare errno */
47 extern int errno;
48 extern int sys_nerr;
49 extern char *sys_errlist[];
50
51 #include <sys/param.h>
52 #include <X11/cursorfont.h>
53 #include <X11/Intrinsic.h>
54 #include <X11/StringDefs.h>
55 #include <X11/Composite.h>
56 #include <X11/Shell.h>
57 #include <X11/Xaw/Form.h>
58 #include <X11/Xaw/Command.h>
59 #include <X11/Xaw/Scrollbar.h>
60 #include <X11/Xaw/Label.h>
61
62 #include "SFinternal.h"
63
64 #ifndef MAXPATHLEN
65 #define MAXPATHLEN 1024
66 #endif /* ndef MAXPATHLEN */
67
68 #if !defined(SVR4) && !defined(SYSV) && !defined(USG)
69 extern char *getwd();
70 #endif /* !defined(SVR4) && !defined(SYSV) && !defined(USG) */
71
72 int SFstatus = SEL_FILE_NULL;
73
74 char
75 SFstartDir[MAXPATHLEN],
76 SFcurrentPath[MAXPATHLEN],
77 SFcurrentDir[MAXPATHLEN];
78
79 Widget
80 selFile,
81 selFileCancel,
82 selFileField,
83 selFileForm,
84 selFileHScroll,
85 selFileHScrolls[3],
86 selFileLists[3],
87 selFileOK,
88 selFilePrompt,
89 selFileVScrolls[3];
90
91 Display *SFdisplay;
92
93 Pixel SFfore, SFback;
94
95 Atom SFwmDeleteWindow;
96
97 XSegment SFsegs[2], SFcompletionSegs[2];
98
99 XawTextPosition SFtextPos;
100
101 int SFupperX, SFlowerY, SFupperY;
102
103 int SFtextX, SFtextYoffset;
104
105 int SFentryWidth, SFentryHeight;
106
107 int SFlineToTextH = 3;
108
109 int SFlineToTextV = 3;
110
111 int SFbesideText = 3;
112
113 int SFaboveAndBelowText = 2;
114
115 int SFcharsPerEntry = 15;
116
117 int SFlistSize = 10;
118
119 int SFworkProcAdded = 0;
120
121 XtAppContext SFapp;
122
123 int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
124
125 char SFtextBuffer[MAXPATHLEN];
126
127 XtIntervalId SFdirModTimerId;
128
129 int (*SFfunc)();
130
131 static char *oneLineTextEditTranslations = "\
132 <Key>Return: redraw-display()\n\
133 Ctrl<Key>M: redraw-display()\n\
134 ";
135
136 /* ARGSUSED */
137 static void
138 SFexposeList(w, n, event)
139 Widget w;
140 int n;
141 XExposeEvent *event;
142 {
143 if ((event->type == NoExpose) || event->count) {
144 return;
145 }
146
147 SFdrawList(n, SF_DO_NOT_SCROLL);
148 }
149
150 /* ARGSUSED */
151 static void
152 SFmodVerifyCallback(w, client_data, event)
153 Widget w;
154 XtPointer client_data;
155 XKeyPressedEvent *event;
156 {
157 char buf[2];
158
159 if (
160 (XLookupString(event, buf, 2, NULL, NULL) == 1) &&
161 ((*buf) == '\r')
162 ) {
163 SFstatus = SEL_FILE_OK;
164 } else {
165 SFstatus = SEL_FILE_TEXT;
166 }
167 }
168
169 /* ARGSUSED */
170 static void
171 SFokCallback(w)
172 Widget w;
173 {
174 SFstatus = SEL_FILE_OK;
175 }
176
177 static XtCallbackRec SFokSelect[] = {
178 { SFokCallback, (XtPointer) NULL },
179 { NULL, (XtPointer) NULL },
180 };
181
182 /* ARGSUSED */
183 static void
184 SFcancelCallback(w)
185 Widget w;
186 {
187 SFstatus = SEL_FILE_CANCEL;
188 }
189
190 static XtCallbackRec SFcancelSelect[] = {
191 { SFcancelCallback, (XtPointer) NULL },
192 { NULL, (XtPointer) NULL },
193 };
194
195 /* ARGSUSED */
196 static void
197 SFdismissAction(w, event, params, num_params)
198 Widget w;
199 XEvent *event;
200 String *params;
201 Cardinal *num_params;
202 {
203 if (event->type == ClientMessage &&
204 event->xclient.data.l[0] != SFwmDeleteWindow) return;
205
206 SFstatus = SEL_FILE_CANCEL;
207 }
208
209 static char *wmDeleteWindowTranslation = "\
210 <Message>WM_PROTOCOLS: SelFileDismiss()\n\
211 ";
212
213 static XtActionsRec actions[] = {
214 {"SelFileDismiss", SFdismissAction},
215 };
216
217 static void
218 SFcreateWidgets(toplevel, prompt, ok, cancel)
219 Widget toplevel;
220 char *prompt;
221 char *ok;
222 char *cancel;
223 {
224 int i, n;
225 int listWidth, listHeight;
226 int listSpacing = 10;
227 int scrollThickness = 15;
228 int hScrollX, hScrollY;
229 int vScrollX, vScrollY;
230 Cursor
231 xtermCursor,
232 sbRightArrowCursor,
233 dotCursor;
234 Arg arglist[20];
235
236 i = 0;
237 XtSetArg(arglist[i], XtNtransientFor, toplevel); i++;
238
239 selFile = XtAppCreateShell("selFile", "SelFile",
240 transientShellWidgetClass, SFdisplay, arglist, i);
241
242 /* Add WM_DELETE_WINDOW protocol */
243 XtAppAddActions(XtWidgetToApplicationContext(selFile),
244 actions, XtNumber(actions));
245 XtOverrideTranslations(selFile,
246 XtParseTranslationTable(wmDeleteWindowTranslation));
247
248 i = 0;
249 XtSetArg(arglist[i], XtNdefaultDistance, 30); i++;
250 selFileForm = XtCreateManagedWidget("selFileForm",
251 formWidgetClass, selFile, arglist, i);
252
253 i = 0;
254 XtSetArg(arglist[i], XtNlabel, prompt); i++;
255 XtSetArg(arglist[i], XtNresizable, True); i++;
256 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
257 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
258 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
259 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
260 XtSetArg(arglist[i], XtNborderWidth, 0); i++;
261 selFilePrompt = XtCreateManagedWidget("selFilePrompt",
262 labelWidgetClass, selFileForm, arglist, i);
263
264 i = 0;
265 XtSetArg(arglist[i], XtNforeground, &SFfore); i++;
266 XtSetArg(arglist[i], XtNbackground, &SFback); i++;
267 XtGetValues(selFilePrompt, arglist, i);
268
269 SFinitFont();
270
271 SFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth +
272 SFbesideText;
273 SFentryHeight = SFaboveAndBelowText + SFcharHeight +
274 SFaboveAndBelowText;
275
276 listWidth = SFlineToTextH + SFentryWidth + SFlineToTextH + 1 +
277 scrollThickness;
278 listHeight = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
279 SFlineToTextV + SFlistSize * SFentryHeight +
280 SFlineToTextV + 1 + scrollThickness;
281
282 SFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4;
283
284 hScrollX = -1;
285 hScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
286 SFlineToTextV + SFlistSize * SFentryHeight +
287 SFlineToTextV;
288 SFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH;
289
290 vScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH;
291 vScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV;
292 SFvScrollHeight = SFlineToTextV + SFlistSize * SFentryHeight +
293 SFlineToTextV;
294
295 SFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1;
296 SFlowerY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
297 SFlineToTextV;
298 SFupperY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
299 SFlineToTextV + SFlistSize * SFentryHeight - 1;
300
301 SFtextX = SFlineToTextH + SFbesideText;
302 SFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent;
303
304 SFsegs[0].x1 = 0;
305 SFsegs[0].y1 = vScrollY;
306 SFsegs[0].x2 = vScrollX - 1;
307 SFsegs[0].y2 = vScrollY;
308 SFsegs[1].x1 = vScrollX;
309 SFsegs[1].y1 = 0;
310 SFsegs[1].x2 = vScrollX;
311 SFsegs[1].y2 = vScrollY - 1;
312
313 SFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH;
314 SFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 =
315 SFlineToTextH + SFentryWidth - 1;
316
317 i = 0;
318 XtSetArg(arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4);
319 i++;
320 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
321
322 XtSetArg(arglist[i], XtNfromVert, selFilePrompt); i++;
323 XtSetArg(arglist[i], XtNvertDistance, 10); i++;
324 XtSetArg(arglist[i], XtNresizable, True); i++;
325 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
326 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
327 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
328 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
329 XtSetArg(arglist[i], XtNstring, SFtextBuffer); i++;
330 XtSetArg(arglist[i], XtNlength, MAXPATHLEN); i++;
331 XtSetArg(arglist[i], XtNeditType, XawtextEdit); i++;
332 XtSetArg(arglist[i], XtNwrap, XawtextWrapWord); i++;
333 XtSetArg(arglist[i], XtNresize, XawtextResizeHeight); i++;
334 XtSetArg(arglist[i], XtNuseStringInPlace, True); i++;
335 selFileField = XtCreateManagedWidget("selFileField",
336 asciiTextWidgetClass, selFileForm, arglist, i);
337
338 XtOverrideTranslations(selFileField,
339 XtParseTranslationTable(oneLineTextEditTranslations));
340 XtSetKeyboardFocus(selFileForm, selFileField);
341
342 i = 0;
343 XtSetArg(arglist[i], XtNorientation, XtorientHorizontal); i++;
344 XtSetArg(arglist[i], XtNwidth, SFpathScrollWidth); i++;
345 XtSetArg(arglist[i], XtNheight, scrollThickness); i++;
346 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
347 XtSetArg(arglist[i], XtNfromVert, selFileField); i++;
348 XtSetArg(arglist[i], XtNvertDistance, 30); i++;
349 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
350 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
351 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
352 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
353 selFileHScroll = XtCreateManagedWidget("selFileHScroll",
354 scrollbarWidgetClass, selFileForm, arglist, i);
355
356 XtAddCallback(selFileHScroll, XtNjumpProc,
357 SFpathSliderMovedCallback, (XtPointer) NULL);
358 XtAddCallback(selFileHScroll, XtNscrollProc,
359 SFpathAreaSelectedCallback, (XtPointer) NULL);
360
361 i = 0;
362 XtSetArg(arglist[i], XtNwidth, listWidth); i++;
363 XtSetArg(arglist[i], XtNheight, listHeight); i++;
364 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
365 XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
366 XtSetArg(arglist[i], XtNvertDistance, 10); i++;
367 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
368 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
369 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
370 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
371 selFileLists[0] = XtCreateManagedWidget("selFileList1",
372 compositeWidgetClass, selFileForm, arglist, i);
373
374 i = 0;
375 XtSetArg(arglist[i], XtNwidth, listWidth); i++;
376 XtSetArg(arglist[i], XtNheight, listHeight); i++;
377 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
378 XtSetArg(arglist[i], XtNfromHoriz, selFileLists[0]); i++;
379 XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
380 XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++;
381 XtSetArg(arglist[i], XtNvertDistance, 10); i++;
382 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
383 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
384 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
385 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
386 selFileLists[1] = XtCreateManagedWidget("selFileList2",
387 compositeWidgetClass, selFileForm, arglist, i);
388
389 i = 0;
390 XtSetArg(arglist[i], XtNwidth, listWidth); i++;
391 XtSetArg(arglist[i], XtNheight, listHeight); i++;
392 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
393 XtSetArg(arglist[i], XtNfromHoriz, selFileLists[1]); i++;
394 XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++;
395 XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++;
396 XtSetArg(arglist[i], XtNvertDistance, 10); i++;
397 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
398 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
399 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
400 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
401 selFileLists[2] = XtCreateManagedWidget("selFileList3",
402 compositeWidgetClass, selFileForm, arglist, i);
403
404 for (n = 0; n < 3; n++) {
405
406 i = 0;
407 XtSetArg(arglist[i], XtNx, vScrollX); i++;
408 XtSetArg(arglist[i], XtNy, vScrollY); i++;
409 XtSetArg(arglist[i], XtNwidth, scrollThickness); i++;
410 XtSetArg(arglist[i], XtNheight, SFvScrollHeight); i++;
411 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
412 selFileVScrolls[n] = XtCreateManagedWidget("selFileVScroll",
413 scrollbarWidgetClass, selFileLists[n], arglist, i);
414
415 XtAddCallback(selFileVScrolls[n], XtNjumpProc,
416 SFvFloatSliderMovedCallback, (XtPointer) n);
417 XtAddCallback(selFileVScrolls[n], XtNscrollProc,
418 SFvAreaSelectedCallback, (XtPointer) n);
419
420 i = 0;
421
422 XtSetArg(arglist[i], XtNorientation, XtorientHorizontal);
423 i++;
424 XtSetArg(arglist[i], XtNx, hScrollX); i++;
425 XtSetArg(arglist[i], XtNy, hScrollY); i++;
426 XtSetArg(arglist[i], XtNwidth, SFhScrollWidth); i++;
427 XtSetArg(arglist[i], XtNheight, scrollThickness); i++;
428 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
429 selFileHScrolls[n] = XtCreateManagedWidget("selFileHScroll",
430 scrollbarWidgetClass, selFileLists[n], arglist, i);
431
432 XtAddCallback(selFileHScrolls[n], XtNjumpProc,
433 SFhSliderMovedCallback, (XtPointer) n);
434 XtAddCallback(selFileHScrolls[n], XtNscrollProc,
435 SFhAreaSelectedCallback, (XtPointer) n);
436 }
437
438 i = 0;
439 XtSetArg(arglist[i], XtNlabel, ok); i++;
440 XtSetArg(arglist[i], XtNresizable, True); i++;
441 XtSetArg(arglist[i], XtNcallback, SFokSelect); i++;
442 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
443 XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++;
444 XtSetArg(arglist[i], XtNvertDistance, 30); i++;
445 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
446 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
447 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
448 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
449 selFileOK = XtCreateManagedWidget("selFileOK", commandWidgetClass,
450 selFileForm, arglist, i);
451
452 i = 0;
453 XtSetArg(arglist[i], XtNlabel, cancel); i++;
454 XtSetArg(arglist[i], XtNresizable, True); i++;
455 XtSetArg(arglist[i], XtNcallback, SFcancelSelect); i++;
456 XtSetArg(arglist[i], XtNborderColor, SFfore); i++;
457 XtSetArg(arglist[i], XtNfromHoriz, selFileOK); i++;
458 XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++;
459 XtSetArg(arglist[i], XtNhorizDistance, 30); i++;
460 XtSetArg(arglist[i], XtNvertDistance, 30); i++;
461 XtSetArg(arglist[i], XtNtop, XtChainTop); i++;
462 XtSetArg(arglist[i], XtNbottom, XtChainTop); i++;
463 XtSetArg(arglist[i], XtNleft, XtChainLeft); i++;
464 XtSetArg(arglist[i], XtNright, XtChainLeft); i++;
465 selFileCancel = XtCreateManagedWidget("selFileCancel",
466 commandWidgetClass, selFileForm, arglist, i);
467
468 XtSetMappedWhenManaged(selFile, False);
469 XtRealizeWidget(selFile);
470
471 /* Add WM_DELETE_WINDOW protocol */
472 SFwmDeleteWindow = XInternAtom(SFdisplay, "WM_DELETE_WINDOW", False);
473 XSetWMProtocols(SFdisplay, XtWindow(selFile), &SFwmDeleteWindow, 1);
474
475 SFcreateGC();
476
477 xtermCursor = XCreateFontCursor(SFdisplay, XC_xterm);
478
479 sbRightArrowCursor = XCreateFontCursor(SFdisplay, XC_sb_right_arrow);
480 dotCursor = XCreateFontCursor(SFdisplay, XC_dot);
481
482 XDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor);
483 XDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor);
484
485 for (n = 0; n < 3; n++) {
486 XDefineCursor(SFdisplay, XtWindow(selFileLists[n]),
487 sbRightArrowCursor);
488 }
489 XDefineCursor(SFdisplay, XtWindow(selFileOK), dotCursor);
490 XDefineCursor(SFdisplay, XtWindow(selFileCancel), dotCursor);
491
492 for (n = 0; n < 3; n++) {
493 XtAddEventHandler(selFileLists[n], ExposureMask, True,
494 SFexposeList, (XtPointer) n);
495 XtAddEventHandler(selFileLists[n], EnterWindowMask, False,
496 SFenterList, (XtPointer) n);
497 XtAddEventHandler(selFileLists[n], LeaveWindowMask, False,
498 SFleaveList, (XtPointer) n);
499 XtAddEventHandler(selFileLists[n], PointerMotionMask, False,
500 SFmotionList, (XtPointer) n);
501 XtAddEventHandler(selFileLists[n], ButtonPressMask, False,
502 SFbuttonPressList, (XtPointer) n);
503 XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False,
504 SFbuttonReleaseList, (XtPointer) n);
505 }
506
507 XtAddEventHandler(selFileField, KeyPressMask, False,
508 SFmodVerifyCallback, (XtPointer) NULL);
509
510 SFapp = XtWidgetToApplicationContext(selFile);
511
512 }
513
514 /* position widget under the cursor */
515 void
516 SFpositionWidget(w)
517 Widget w;
518 {
519 Arg args[3];
520 Cardinal num_args;
521 Dimension width, height, b_width;
522 int x, y, max_x, max_y;
523 Window root, child;
524 int dummyx, dummyy;
525 unsigned int dummymask;
526
527 XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
528 &dummyx, &dummyy, &dummymask);
529 num_args = 0;
530 XtSetArg(args[num_args], XtNwidth, &width); num_args++;
531 XtSetArg(args[num_args], XtNheight, &height); num_args++;
532 XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
533 XtGetValues(w, args, num_args);
534
535 width += 2 * b_width;
536 height += 2 * b_width;
537
538 x -= ( (Position) width/2 );
539 if (x < 0) x = 0;
540 if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
541
542 y -= ( (Position) height/2 );
543 if (y < 0) y = 0;
544 if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
545
546 num_args = 0;
547 XtSetArg(args[num_args], XtNx, x); num_args++;
548 XtSetArg(args[num_args], XtNy, y); num_args++;
549 XtSetValues(w, args, num_args);
550 }
551
552 FILE *
553 SFopenFile(name, mode, prompt, failed)
554 char *name;
555 char *mode;
556 char *prompt;
557 char *failed;
558 {
559 Arg args[1];
560 FILE *fp;
561
562 SFchdir(SFstartDir);
563 if ((fp = fopen(name, mode)) == NULL) {
564 char *buf;
565 if (errno <= sys_nerr) {
566 buf = XtMalloc(strlen(failed) + strlen(sys_errlist[errno]) +
567 strlen(prompt) + 2);
568 strcpy(buf, failed);
569 strcat(buf, sys_errlist[errno]);
570 strcat(buf, "\n");
571 strcat(buf, prompt);
572 } else {
573 buf = XtMalloc(strlen(failed) + strlen(prompt) + 2);
574 strcpy(buf, failed);
575 strcat(buf, "\n");
576 strcat(buf, prompt);
577 }
578 XtSetArg(args[0], XtNlabel, buf);
579 XtSetValues(selFilePrompt, args, 1);
580 XtFree(buf);
581 return NULL;
582 }
583 return fp;
584 }
585
586 SFtextChanged()
587 {
588
589 if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
590 (void) strcpy(SFcurrentPath, SFtextBuffer);
591
592 SFtextPos = XawTextGetInsertionPoint(selFileField);
593 } else {
594 (void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer);
595
596 SFtextPos = XawTextGetInsertionPoint(selFileField) +
597 strlen(SFstartDir);
598 }
599
600 if (!SFworkProcAdded) {
601 (void) XtAppAddWorkProc(SFapp, SFworkProc, NULL);
602 SFworkProcAdded = 1;
603 }
604
605 SFupdatePath();
606 }
607
608 static char *
609 SFgetText()
610 {
611 return strcpy(XtMalloc((unsigned) (strlen(SFtextBuffer) + 1)),
612 SFtextBuffer);
613 }
614
615 static
616 SFprepareToReturn()
617 {
618 SFstatus = SEL_FILE_NULL;
619 XtRemoveGrab(selFile);
620 XtUnmapWidget(selFile);
621 XtRemoveTimeOut(SFdirModTimerId);
622 if (SFchdir(SFstartDir)) {
623 XtAppError(
624 SFapp,
625 "XsraSelFile: can't return to current directory"
626 );
627 }
628 }
629
630 FILE *
631 XsraSelFile(toplevel, prompt, ok, cancel, failed,
632 init_path, mode, show_entry, name_return)
633 Widget toplevel;
634 char *prompt;
635 char *ok;
636 char *cancel;
637 char *failed;
638 char *init_path;
639 char *mode;
640 int (*show_entry)();
641 char **name_return;
642 {
643 static int firstTime = 1;
644 int i;
645 Arg arglist[20];
646 XEvent event;
647 FILE *fp;
648
649 if (!prompt) {
650 prompt = "Pathname:";
651 }
652
653 if (!ok) {
654 ok = "OK";
655 }
656
657 if (!cancel) {
658 cancel = "Cancel";
659 }
660
661 if (firstTime) {
662 firstTime = 0;
663 SFdisplay = XtDisplay(toplevel);
664 SFcreateWidgets(toplevel, prompt, ok, cancel);
665 } else {
666 i = 0;
667
668 XtSetArg(arglist[i], XtNlabel, prompt); i++;
669 XtSetValues(selFilePrompt, arglist, i);
670
671 i = 0;
672 XtSetArg(arglist[i], XtNlabel, ok); i++;
673 XtSetValues(selFileOK, arglist, i);
674
675 i = 0;
676 XtSetArg(arglist[i], XtNlabel, cancel); i++;
677 XtSetValues(selFileCancel, arglist, i);
678 }
679
680 SFpositionWidget(selFile);
681 XtMapWidget(selFile);
682
683 #if defined(SVR4) || defined(SYSV) || defined(USG)
684 if (!getcwd(SFstartDir, MAXPATHLEN)) {
685 #else /* defined(SVR4) || defined(SYSV) || defined(USG) */
686 if (!getwd(SFstartDir)) {
687 #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
688
689 XtAppError(SFapp, "XsraSelFile: can't get current directory");
690 }
691 (void) strcat(SFstartDir, "/");
692 (void) strcpy(SFcurrentDir, SFstartDir);
693
694 if (init_path) {
695 if (init_path[0] == '/') {
696 (void) strcpy(SFcurrentPath, init_path);
697 if (strncmp(
698 SFcurrentPath,
699 SFstartDir,
700 strlen(SFstartDir)
701 )) {
702 SFsetText(SFcurrentPath);
703 } else {
704 SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
705 }
706 } else {
707 (void) strcat(strcpy(SFcurrentPath, SFstartDir),
708 init_path);
709 SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
710 }
711 } else {
712 (void) strcpy(SFcurrentPath, SFstartDir);
713 }
714
715 SFfunc = show_entry;
716
717 SFtextChanged();
718
719 XtAddGrab(selFile, True, True);
720
721 SFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000,
722 SFdirModTimer, (XtPointer) NULL);
723
724 while (1) {
725 XtAppNextEvent(SFapp, &event);
726 XtDispatchEvent(&event);
727 switch (SFstatus) {
728 case SEL_FILE_TEXT:
729 SFstatus = SEL_FILE_NULL;
730 SFtextChanged();
731 break;
732 case SEL_FILE_OK:
733 *name_return = SFgetText();
734 if (fp = SFopenFile(*name_return, mode,
735 prompt, failed)) {
736 SFprepareToReturn();
737 return fp;
738 }
739 SFstatus = SEL_FILE_NULL;
740 break;
741 case SEL_FILE_CANCEL:
742 SFprepareToReturn();
743 return NULL;
744 case SEL_FILE_NULL:
745 break;
746 }
747 }
748 }