1 | /* |
---|
2 | * Modifications Copyright 1996 by Paul Mattes. |
---|
3 | * Copyright Octover 1995 by Dick Altenbern. |
---|
4 | * Based in part on code Copyright 1993, 1994, 1995 by Paul Mattes. |
---|
5 | * Permission to use, copy, modify, and distribute this software and its |
---|
6 | * documentation for any purpose and without fee is hereby granted, |
---|
7 | * provided that the above copyright notice appear in all copies and that |
---|
8 | * both that copyright notice and this permission notice appear in |
---|
9 | * supporting documentation. |
---|
10 | */ |
---|
11 | |
---|
12 | /* |
---|
13 | * ft.c |
---|
14 | * This module handles the file transfer dialogs. |
---|
15 | */ |
---|
16 | |
---|
17 | #include "globals.h" |
---|
18 | |
---|
19 | #include <X11/StringDefs.h> |
---|
20 | #include <X11/Xaw/Toggle.h> |
---|
21 | #include <X11/Xaw/Command.h> |
---|
22 | #include <X11/Xaw/Form.h> |
---|
23 | #include <X11/Shell.h> |
---|
24 | #include <X11/Xaw/AsciiText.h> |
---|
25 | #include <X11/Xaw/TextSrc.h> |
---|
26 | #include <X11/Xaw/TextSink.h> |
---|
27 | #include <X11/Xaw/AsciiSrc.h> |
---|
28 | #include <X11/Xaw/AsciiSink.h> |
---|
29 | #include <errno.h> |
---|
30 | |
---|
31 | #if XtSpecificationRelease < 5 /*[*/ |
---|
32 | #define TOGGLE_HACK 1 |
---|
33 | #endif /*]*/ |
---|
34 | |
---|
35 | #include "appres.h" |
---|
36 | #include "actionsc.h" |
---|
37 | #include "ft_cutc.h" |
---|
38 | #include "ft_dftc.h" |
---|
39 | #include "ftc.h" |
---|
40 | #include "kybdc.h" |
---|
41 | #include "objects.h" |
---|
42 | #include "popupsc.h" |
---|
43 | #include "telnetc.h" |
---|
44 | #include "utilc.h" |
---|
45 | |
---|
46 | /* Macros. */ |
---|
47 | #define eos(s) strchr((s), '\0') |
---|
48 | |
---|
49 | #define FILE_WIDTH 300 /* width of file name widgets */ |
---|
50 | #define MARGIN 3 /* distance from margins to widgets */ |
---|
51 | #define CLOSE_VGAP 0 /* distance between paired toggles */ |
---|
52 | #define FAR_VGAP 10 /* distance between single toggles and groups */ |
---|
53 | #define BUTTON_GAP 5 /* horizontal distance between buttons */ |
---|
54 | #define COLUMN_GAP 40 /* distance between columns */ |
---|
55 | |
---|
56 | /* Externals. */ |
---|
57 | extern Pixmap diamond; |
---|
58 | extern Pixmap no_diamond; |
---|
59 | extern Pixmap null; |
---|
60 | extern Pixmap dot; |
---|
61 | |
---|
62 | /* Globals. */ |
---|
63 | enum ft_state ft_state = FT_NONE; /* File transfer state */ |
---|
64 | char *ft_local_filename; /* Local file to transfer to/from */ |
---|
65 | FILE *ft_local_file = (FILE *)NULL; /* File descriptor for local file */ |
---|
66 | Boolean ascii_flag = True; /* Convert to ascii */ |
---|
67 | Boolean cr_flag = True; /* Add crlf to each line */ |
---|
68 | unsigned long ft_length = 0; /* Length of transfer */ |
---|
69 | |
---|
70 | /* Statics. */ |
---|
71 | static Widget ft_dialog, ft_shell, local_file, host_file; |
---|
72 | static Widget lrecl_widget, blksize_widget; |
---|
73 | static Widget primspace_widget, secspace_widget; |
---|
74 | static Widget send_toggle, receive_toggle; |
---|
75 | static Widget vm_toggle, tso_toggle; |
---|
76 | static Widget ascii_toggle, binary_toggle; |
---|
77 | static Widget cr_widget; |
---|
78 | |
---|
79 | static Boolean receive_flag = True; /* Current transfer is receive */ |
---|
80 | static Boolean append_flag = False; /* Append transfer */ |
---|
81 | static Boolean vm_flag = False; /* VM Transfer flag */ |
---|
82 | |
---|
83 | struct toggle_list { /* List of toggle widgets */ |
---|
84 | Widget *widgets; |
---|
85 | }; |
---|
86 | static Widget recfm_options[5]; |
---|
87 | static Widget units_options[5]; |
---|
88 | static struct toggle_list recfm_toggles = { recfm_options }; |
---|
89 | static struct toggle_list units_toggles = { units_options }; |
---|
90 | |
---|
91 | static enum recfm { |
---|
92 | DEFAULT_RECFM, FIXED, VARIABLE, UNDEFINED |
---|
93 | } recfm = DEFAULT_RECFM; |
---|
94 | static Boolean recfm_default = True; |
---|
95 | static enum recfm r_default_recfm = DEFAULT_RECFM; |
---|
96 | static enum recfm r_fixed = FIXED; |
---|
97 | static enum recfm r_variable = VARIABLE; |
---|
98 | static enum recfm r_undefined = UNDEFINED; |
---|
99 | |
---|
100 | static enum units { |
---|
101 | DEFAULT_UNITS, TRACKS, CYLINDERS, AVBLOCK |
---|
102 | } units = DEFAULT_UNITS; |
---|
103 | static Boolean units_default = True; |
---|
104 | static enum units u_default_units = DEFAULT_UNITS; |
---|
105 | static enum units u_tracks = TRACKS; |
---|
106 | static enum units u_cylinders = CYLINDERS; |
---|
107 | static enum units u_avblock = AVBLOCK; |
---|
108 | |
---|
109 | typedef enum { T_NUMERIC, T_HOSTFILE, T_UNIXFILE } text_t; |
---|
110 | static text_t t_numeric = T_NUMERIC; |
---|
111 | static text_t t_hostfile = T_HOSTFILE; |
---|
112 | static text_t t_unixfile = T_UNIXFILE; |
---|
113 | |
---|
114 | static Boolean s_true = True; |
---|
115 | static Boolean s_false = False; |
---|
116 | static Boolean allow_overwrite = False; |
---|
117 | typedef struct sr { |
---|
118 | struct sr *next; |
---|
119 | Widget w; |
---|
120 | Boolean *bvar1; |
---|
121 | Boolean bval1; |
---|
122 | Boolean *bvar2; |
---|
123 | Boolean bval2; |
---|
124 | Boolean *bvar3; |
---|
125 | Boolean bval3; |
---|
126 | Boolean is_value; |
---|
127 | Boolean has_focus; |
---|
128 | } sr_t; |
---|
129 | sr_t *sr = (sr_t *)NULL; |
---|
130 | sr_t *sr_last = (sr_t *)NULL; |
---|
131 | |
---|
132 | static Widget progress_shell, from_file, to_file; |
---|
133 | static Widget ft_status, waiting, aborting; |
---|
134 | static String status_string; |
---|
135 | static struct timeval t0; /* Starting time */ |
---|
136 | static Boolean ft_is_cut; /* File transfer is CUT-style */ |
---|
137 | |
---|
138 | static Widget overwrite_shell; |
---|
139 | |
---|
140 | static void apply_bitmap(); |
---|
141 | static void check_sensitivity(); |
---|
142 | static void flip_toggles(); |
---|
143 | static void focus_next(); |
---|
144 | static void ft_cancel(); |
---|
145 | static void ft_popup_callback(); |
---|
146 | static void ft_popup_init(); |
---|
147 | static int ft_start(); |
---|
148 | static void ft_start_callback(); |
---|
149 | static void match_dimension(); |
---|
150 | static void overwrite_cancel_callback(); |
---|
151 | static void overwrite_okay_callback(); |
---|
152 | static void overwrite_popdown(); |
---|
153 | static void overwrite_popup_init(); |
---|
154 | static void popup_overwrite(); |
---|
155 | static void popup_progress(); |
---|
156 | static void progress_cancel_callback(); |
---|
157 | static void progress_popup_callback(); |
---|
158 | static void progress_popup_init(); |
---|
159 | static void recfm_callback(); |
---|
160 | static void register_sensitivity(); |
---|
161 | static void text_callback(); |
---|
162 | static void toggle_append(); |
---|
163 | static void toggle_ascii(); |
---|
164 | static void toggle_cr(); |
---|
165 | static void toggle_receive(); |
---|
166 | static void toggle_vm(); |
---|
167 | static void units_callback(); |
---|
168 | |
---|
169 | /* Main external entry point. */ |
---|
170 | |
---|
171 | /* "File Transfer" dialog. */ |
---|
172 | |
---|
173 | /* |
---|
174 | * Pop up the "Transfer" menu. |
---|
175 | * Called back from the "File Transfer" option on the File menu. |
---|
176 | */ |
---|
177 | void |
---|
178 | popup_ft(w, call_parms, call_data) |
---|
179 | Widget w; |
---|
180 | XtPointer call_parms; |
---|
181 | XtPointer call_data; |
---|
182 | { |
---|
183 | /* Initialize it. */ |
---|
184 | if (ft_shell == (Widget)NULL) |
---|
185 | ft_popup_init(); |
---|
186 | |
---|
187 | /* Pop it up. */ |
---|
188 | popup_popup(ft_shell, XtGrabNone); |
---|
189 | } |
---|
190 | |
---|
191 | |
---|
192 | /* Initialize the transfer pop-up. */ |
---|
193 | static void |
---|
194 | ft_popup_init() |
---|
195 | { |
---|
196 | Widget w; |
---|
197 | Widget cancel_button; |
---|
198 | Widget local_label, host_label; |
---|
199 | Widget append_widget; |
---|
200 | Widget lrecl_label, blksize_label, primspace_label, secspace_label; |
---|
201 | Widget h_ref = (Widget)NULL; |
---|
202 | Dimension d1; |
---|
203 | Dimension maxw = 0; |
---|
204 | Widget recfm_label, units_label; |
---|
205 | Widget start_button; |
---|
206 | |
---|
207 | /* Create the menu shell. */ |
---|
208 | ft_shell = XtVaCreatePopupShell( |
---|
209 | "ftPopup", transientShellWidgetClass, toplevel, |
---|
210 | NULL); |
---|
211 | XtAddCallback(ft_shell, XtNpopupCallback, place_popup, |
---|
212 | (XtPointer)CenterP); |
---|
213 | XtAddCallback(ft_shell, XtNpopupCallback, ft_popup_callback, |
---|
214 | (XtPointer)NULL); |
---|
215 | |
---|
216 | /* Create the form within the shell. */ |
---|
217 | ft_dialog = XtVaCreateManagedWidget( |
---|
218 | "dialog", formWidgetClass, ft_shell, |
---|
219 | NULL); |
---|
220 | |
---|
221 | /* Create the file name widgets. */ |
---|
222 | local_label = XtVaCreateManagedWidget( |
---|
223 | "local", labelWidgetClass, ft_dialog, |
---|
224 | XtNvertDistance, FAR_VGAP, |
---|
225 | XtNhorizDistance, MARGIN, |
---|
226 | XtNborderWidth, 0, |
---|
227 | NULL); |
---|
228 | local_file = XtVaCreateManagedWidget( |
---|
229 | "value", asciiTextWidgetClass, ft_dialog, |
---|
230 | XtNeditType, XawtextEdit, |
---|
231 | XtNwidth, FILE_WIDTH, |
---|
232 | XtNvertDistance, FAR_VGAP, |
---|
233 | XtNfromHoriz, local_label, |
---|
234 | XtNhorizDistance, 0, |
---|
235 | NULL); |
---|
236 | match_dimension(local_label, local_file, XtNheight); |
---|
237 | w = XawTextGetSource(local_file); |
---|
238 | if (w == NULL) |
---|
239 | XtWarning("Cannot find text source in dialog"); |
---|
240 | else |
---|
241 | XtAddCallback(w, XtNcallback, text_callback, |
---|
242 | (XtPointer)&t_unixfile); |
---|
243 | register_sensitivity(local_file, |
---|
244 | NULL, NULL, |
---|
245 | NULL, NULL, |
---|
246 | NULL, NULL); |
---|
247 | |
---|
248 | host_label = XtVaCreateManagedWidget( |
---|
249 | "host", labelWidgetClass, ft_dialog, |
---|
250 | XtNfromVert, local_label, |
---|
251 | XtNvertDistance, 3, |
---|
252 | XtNhorizDistance, MARGIN, |
---|
253 | XtNborderWidth, 0, |
---|
254 | NULL); |
---|
255 | host_file = XtVaCreateManagedWidget( |
---|
256 | "value", asciiTextWidgetClass, ft_dialog, |
---|
257 | XtNeditType, XawtextEdit, |
---|
258 | XtNwidth, FILE_WIDTH, |
---|
259 | XtNdisplayCaret, False, |
---|
260 | XtNfromVert, local_label, |
---|
261 | XtNvertDistance, 3, |
---|
262 | XtNfromHoriz, host_label, |
---|
263 | XtNhorizDistance, 0, |
---|
264 | NULL); |
---|
265 | match_dimension(host_label, host_file, XtNheight); |
---|
266 | match_dimension(local_label, host_label, XtNwidth); |
---|
267 | w = XawTextGetSource(host_file); |
---|
268 | if (w == NULL) |
---|
269 | XtWarning("Cannot find text source in dialog"); |
---|
270 | else |
---|
271 | XtAddCallback(w, XtNcallback, text_callback, |
---|
272 | (XtPointer)&t_hostfile); |
---|
273 | register_sensitivity(host_file, |
---|
274 | NULL, NULL, |
---|
275 | NULL, NULL, |
---|
276 | NULL, NULL); |
---|
277 | |
---|
278 | /* Create the left column. */ |
---|
279 | |
---|
280 | /* Create send/receive toggles. */ |
---|
281 | send_toggle = XtVaCreateManagedWidget( |
---|
282 | "send", commandWidgetClass, ft_dialog, |
---|
283 | XtNfromVert, host_label, |
---|
284 | XtNvertDistance, FAR_VGAP, |
---|
285 | XtNhorizDistance, MARGIN, |
---|
286 | XtNborderWidth, 0, |
---|
287 | NULL); |
---|
288 | apply_bitmap(send_toggle, receive_flag ? no_diamond : diamond); |
---|
289 | XtAddCallback(send_toggle, XtNcallback, toggle_receive, |
---|
290 | (XtPointer)&s_false); |
---|
291 | receive_toggle = XtVaCreateManagedWidget( |
---|
292 | "receive", commandWidgetClass, ft_dialog, |
---|
293 | XtNfromVert, send_toggle, |
---|
294 | XtNvertDistance, CLOSE_VGAP, |
---|
295 | XtNhorizDistance, MARGIN, |
---|
296 | XtNborderWidth, 0, |
---|
297 | NULL); |
---|
298 | apply_bitmap(receive_toggle, receive_flag ? diamond : no_diamond); |
---|
299 | XtAddCallback(receive_toggle, XtNcallback, toggle_receive, |
---|
300 | (XtPointer)&s_true); |
---|
301 | |
---|
302 | /* Create ASCII/binary toggles. */ |
---|
303 | ascii_toggle = XtVaCreateManagedWidget( |
---|
304 | "ascii", commandWidgetClass, ft_dialog, |
---|
305 | XtNfromVert, receive_toggle, |
---|
306 | XtNvertDistance, FAR_VGAP, |
---|
307 | XtNhorizDistance, MARGIN, |
---|
308 | XtNborderWidth, 0, |
---|
309 | NULL); |
---|
310 | apply_bitmap(ascii_toggle, ascii_flag ? diamond : no_diamond); |
---|
311 | XtAddCallback(ascii_toggle, XtNcallback, toggle_ascii, |
---|
312 | (XtPointer)&s_true); |
---|
313 | binary_toggle = XtVaCreateManagedWidget( |
---|
314 | "binary", commandWidgetClass, ft_dialog, |
---|
315 | XtNfromVert, ascii_toggle, |
---|
316 | XtNvertDistance, CLOSE_VGAP, |
---|
317 | XtNhorizDistance, MARGIN, |
---|
318 | XtNborderWidth, 0, |
---|
319 | NULL); |
---|
320 | apply_bitmap(binary_toggle, ascii_flag ? no_diamond : diamond); |
---|
321 | XtAddCallback(binary_toggle, XtNcallback, toggle_ascii, |
---|
322 | (XtPointer)&s_false); |
---|
323 | |
---|
324 | /* Create append toggle. */ |
---|
325 | append_widget = XtVaCreateManagedWidget( |
---|
326 | "append", commandWidgetClass, ft_dialog, |
---|
327 | XtNfromVert, binary_toggle, |
---|
328 | XtNvertDistance, FAR_VGAP, |
---|
329 | XtNhorizDistance, MARGIN, |
---|
330 | XtNborderWidth, 0, |
---|
331 | NULL); |
---|
332 | apply_bitmap(append_widget, append_flag ? dot : null); |
---|
333 | XtAddCallback(append_widget, XtNcallback, toggle_append, NULL); |
---|
334 | |
---|
335 | /* Set up the recfm group. */ |
---|
336 | recfm_label = XtVaCreateManagedWidget( |
---|
337 | "file", labelWidgetClass, ft_dialog, |
---|
338 | XtNfromVert, append_widget, |
---|
339 | XtNvertDistance, FAR_VGAP, |
---|
340 | XtNhorizDistance, MARGIN, |
---|
341 | XtNborderWidth, 0, |
---|
342 | NULL); |
---|
343 | register_sensitivity(recfm_label, |
---|
344 | &receive_flag, False, |
---|
345 | NULL, NULL, |
---|
346 | NULL, NULL); |
---|
347 | |
---|
348 | recfm_options[0] = XtVaCreateManagedWidget( |
---|
349 | "recfmDefault", commandWidgetClass, ft_dialog, |
---|
350 | XtNfromVert, recfm_label, |
---|
351 | XtNvertDistance, 3, |
---|
352 | XtNhorizDistance, MARGIN, |
---|
353 | XtNborderWidth, 0, |
---|
354 | NULL); |
---|
355 | apply_bitmap(recfm_options[0], |
---|
356 | (recfm == DEFAULT_RECFM) ? diamond : no_diamond); |
---|
357 | XtAddCallback(recfm_options[0], XtNcallback, recfm_callback, |
---|
358 | (XtPointer)&r_default_recfm); |
---|
359 | register_sensitivity(recfm_options[0], |
---|
360 | &receive_flag, False, |
---|
361 | NULL, NULL, |
---|
362 | NULL, NULL); |
---|
363 | |
---|
364 | recfm_options[1] = XtVaCreateManagedWidget( |
---|
365 | "fixed", commandWidgetClass, ft_dialog, |
---|
366 | XtNfromVert, recfm_options[0], |
---|
367 | XtNvertDistance, CLOSE_VGAP, |
---|
368 | XtNhorizDistance, MARGIN, |
---|
369 | XtNborderWidth, 0, |
---|
370 | NULL); |
---|
371 | apply_bitmap(recfm_options[1], |
---|
372 | (recfm == FIXED) ? diamond : no_diamond); |
---|
373 | XtAddCallback(recfm_options[1], XtNcallback, recfm_callback, |
---|
374 | (XtPointer)&r_fixed); |
---|
375 | register_sensitivity(recfm_options[1], |
---|
376 | &receive_flag, False, |
---|
377 | NULL, NULL, |
---|
378 | NULL, NULL); |
---|
379 | |
---|
380 | recfm_options[2] = XtVaCreateManagedWidget( |
---|
381 | "variable", commandWidgetClass, ft_dialog, |
---|
382 | XtNfromVert, recfm_options[1], |
---|
383 | XtNvertDistance, CLOSE_VGAP, |
---|
384 | XtNhorizDistance, MARGIN, |
---|
385 | XtNborderWidth, 0, |
---|
386 | NULL); |
---|
387 | apply_bitmap(recfm_options[2], |
---|
388 | (recfm == VARIABLE) ? diamond : no_diamond); |
---|
389 | XtAddCallback(recfm_options[2], XtNcallback, recfm_callback, |
---|
390 | (XtPointer)&r_variable); |
---|
391 | register_sensitivity(recfm_options[2], |
---|
392 | &receive_flag, False, |
---|
393 | NULL, NULL, |
---|
394 | NULL, NULL); |
---|
395 | |
---|
396 | recfm_options[3] = XtVaCreateManagedWidget( |
---|
397 | "undefined", commandWidgetClass, ft_dialog, |
---|
398 | XtNfromVert, recfm_options[2], |
---|
399 | XtNvertDistance, CLOSE_VGAP, |
---|
400 | XtNhorizDistance, MARGIN, |
---|
401 | XtNborderWidth, 0, |
---|
402 | NULL); |
---|
403 | apply_bitmap(recfm_options[3], |
---|
404 | (recfm == UNDEFINED) ? diamond : no_diamond); |
---|
405 | XtAddCallback(recfm_options[3], XtNcallback, recfm_callback, |
---|
406 | (XtPointer)&r_undefined); |
---|
407 | register_sensitivity(recfm_options[3], |
---|
408 | &receive_flag, False, |
---|
409 | &vm_flag, False, |
---|
410 | NULL, NULL); |
---|
411 | |
---|
412 | lrecl_label = XtVaCreateManagedWidget( |
---|
413 | "lrecl", labelWidgetClass, ft_dialog, |
---|
414 | XtNfromVert, recfm_options[3], |
---|
415 | XtNvertDistance, 3, |
---|
416 | XtNhorizDistance, MARGIN, |
---|
417 | XtNborderWidth, 0, |
---|
418 | NULL); |
---|
419 | register_sensitivity(lrecl_label, |
---|
420 | &receive_flag, False, |
---|
421 | &recfm_default, False, |
---|
422 | NULL, NULL); |
---|
423 | lrecl_widget = XtVaCreateManagedWidget( |
---|
424 | "value", asciiTextWidgetClass, ft_dialog, |
---|
425 | XtNfromVert, recfm_options[3], |
---|
426 | XtNvertDistance, 3, |
---|
427 | XtNfromHoriz, lrecl_label, |
---|
428 | XtNhorizDistance, MARGIN, |
---|
429 | XtNwidth, 100, |
---|
430 | XtNeditType, XawtextEdit, |
---|
431 | XtNdisplayCaret, False, |
---|
432 | NULL); |
---|
433 | match_dimension(lrecl_label, lrecl_widget, XtNheight); |
---|
434 | w = XawTextGetSource(lrecl_widget); |
---|
435 | if (w == NULL) |
---|
436 | XtWarning("Cannot find text source in dialog"); |
---|
437 | else |
---|
438 | XtAddCallback(w, XtNcallback, text_callback, |
---|
439 | (XtPointer)&t_numeric); |
---|
440 | register_sensitivity(lrecl_widget, |
---|
441 | &receive_flag, False, |
---|
442 | &recfm_default, False, |
---|
443 | NULL, NULL); |
---|
444 | |
---|
445 | blksize_label = XtVaCreateManagedWidget( |
---|
446 | "blksize", labelWidgetClass, ft_dialog, |
---|
447 | XtNfromVert, lrecl_widget, |
---|
448 | XtNvertDistance, 3, |
---|
449 | XtNhorizDistance, MARGIN, |
---|
450 | XtNborderWidth, 0, |
---|
451 | NULL); |
---|
452 | match_dimension(blksize_label, lrecl_label, XtNwidth); |
---|
453 | register_sensitivity(blksize_label, |
---|
454 | &receive_flag, False, |
---|
455 | &recfm_default, False, |
---|
456 | NULL, NULL); |
---|
457 | blksize_widget = XtVaCreateManagedWidget( |
---|
458 | "value", asciiTextWidgetClass, ft_dialog, |
---|
459 | XtNfromVert, lrecl_widget, |
---|
460 | XtNvertDistance, 3, |
---|
461 | XtNfromHoriz, blksize_label, |
---|
462 | XtNhorizDistance, MARGIN, |
---|
463 | XtNwidth, 100, |
---|
464 | XtNeditType, XawtextEdit, |
---|
465 | XtNdisplayCaret, False, |
---|
466 | NULL); |
---|
467 | match_dimension(blksize_label, blksize_widget, XtNheight); |
---|
468 | w = XawTextGetSource(blksize_widget); |
---|
469 | if (w == NULL) |
---|
470 | XtWarning("Cannot find text source in dialog"); |
---|
471 | else |
---|
472 | XtAddCallback(w, XtNcallback, text_callback, |
---|
473 | (XtPointer)&t_numeric); |
---|
474 | register_sensitivity(blksize_widget, |
---|
475 | &receive_flag, False, |
---|
476 | &recfm_default, False, |
---|
477 | NULL, NULL); |
---|
478 | |
---|
479 | |
---|
480 | /* Find the widest widget in the left column. */ |
---|
481 | XtVaGetValues(send_toggle, XtNwidth, &maxw, NULL); |
---|
482 | h_ref = send_toggle; |
---|
483 | #define REMAX(w) { \ |
---|
484 | XtVaGetValues((w), XtNwidth, &d1, NULL); \ |
---|
485 | if (d1 > maxw) { \ |
---|
486 | maxw = d1; \ |
---|
487 | h_ref = (w); \ |
---|
488 | } \ |
---|
489 | } |
---|
490 | REMAX(receive_toggle); |
---|
491 | REMAX(ascii_toggle); |
---|
492 | REMAX(binary_toggle); |
---|
493 | REMAX(append_widget); |
---|
494 | #undef REMAX |
---|
495 | |
---|
496 | /* Create the right column buttons. */ |
---|
497 | |
---|
498 | /* Create VM/TSO toggle. */ |
---|
499 | vm_toggle = XtVaCreateManagedWidget( |
---|
500 | "vm", commandWidgetClass, ft_dialog, |
---|
501 | XtNfromVert, host_label, |
---|
502 | XtNvertDistance, FAR_VGAP, |
---|
503 | XtNfromHoriz, h_ref, |
---|
504 | XtNhorizDistance, COLUMN_GAP, |
---|
505 | XtNborderWidth, 0, |
---|
506 | NULL); |
---|
507 | apply_bitmap(vm_toggle, vm_flag ? diamond : no_diamond); |
---|
508 | XtAddCallback(vm_toggle, XtNcallback, toggle_vm, (XtPointer)&s_true); |
---|
509 | tso_toggle = XtVaCreateManagedWidget( |
---|
510 | "tso", commandWidgetClass, ft_dialog, |
---|
511 | XtNfromVert, vm_toggle, |
---|
512 | XtNvertDistance, CLOSE_VGAP, |
---|
513 | XtNfromHoriz, h_ref, |
---|
514 | XtNhorizDistance, COLUMN_GAP, |
---|
515 | XtNborderWidth, 0, |
---|
516 | NULL); |
---|
517 | apply_bitmap(tso_toggle, vm_flag ? no_diamond : diamond); |
---|
518 | XtAddCallback(tso_toggle, XtNcallback, toggle_vm, (XtPointer)&s_false); |
---|
519 | |
---|
520 | /* Create CR toggle. */ |
---|
521 | cr_widget = XtVaCreateManagedWidget( |
---|
522 | "cr", commandWidgetClass, ft_dialog, |
---|
523 | XtNfromVert, tso_toggle, |
---|
524 | XtNvertDistance, FAR_VGAP, |
---|
525 | XtNfromHoriz, h_ref, |
---|
526 | XtNhorizDistance, COLUMN_GAP, |
---|
527 | XtNborderWidth, 0, |
---|
528 | NULL); |
---|
529 | apply_bitmap(cr_widget, cr_flag ? dot : null); |
---|
530 | XtAddCallback(cr_widget, XtNcallback, toggle_cr, 0); |
---|
531 | register_sensitivity(cr_widget, |
---|
532 | &ascii_flag, True, |
---|
533 | NULL, NULL, |
---|
534 | NULL, NULL); |
---|
535 | |
---|
536 | /* Set up the Units group. */ |
---|
537 | units_label = XtVaCreateManagedWidget( |
---|
538 | "units", labelWidgetClass, ft_dialog, |
---|
539 | XtNfromVert, append_widget, |
---|
540 | XtNvertDistance, FAR_VGAP, |
---|
541 | XtNfromHoriz, h_ref, |
---|
542 | XtNhorizDistance, COLUMN_GAP, |
---|
543 | XtNborderWidth, 0, |
---|
544 | NULL); |
---|
545 | register_sensitivity(units_label, |
---|
546 | &receive_flag, False, |
---|
547 | &vm_flag, False, |
---|
548 | NULL, NULL); |
---|
549 | |
---|
550 | units_options[0] = XtVaCreateManagedWidget( |
---|
551 | "spaceDefault", commandWidgetClass, ft_dialog, |
---|
552 | XtNfromVert, units_label, |
---|
553 | XtNvertDistance, 3, |
---|
554 | XtNfromHoriz, h_ref, |
---|
555 | XtNhorizDistance, COLUMN_GAP, |
---|
556 | XtNborderWidth, 0, |
---|
557 | NULL); |
---|
558 | apply_bitmap(units_options[0], |
---|
559 | (units == DEFAULT_UNITS) ? diamond : no_diamond); |
---|
560 | XtAddCallback(units_options[0], XtNcallback, |
---|
561 | units_callback, (XtPointer)&u_default_units); |
---|
562 | register_sensitivity(units_options[0], |
---|
563 | &receive_flag, False, |
---|
564 | &vm_flag, False, |
---|
565 | NULL, NULL); |
---|
566 | |
---|
567 | units_options[1] = XtVaCreateManagedWidget( |
---|
568 | "tracks", commandWidgetClass, ft_dialog, |
---|
569 | XtNfromVert, units_options[0], |
---|
570 | XtNvertDistance, CLOSE_VGAP, |
---|
571 | XtNfromHoriz, h_ref, |
---|
572 | XtNhorizDistance, COLUMN_GAP, |
---|
573 | XtNborderWidth, 0, |
---|
574 | NULL); |
---|
575 | apply_bitmap(units_options[1], |
---|
576 | (units == TRACKS) ? diamond : no_diamond); |
---|
577 | XtAddCallback(units_options[1], XtNcallback, |
---|
578 | units_callback, (XtPointer)&u_tracks); |
---|
579 | register_sensitivity(units_options[1], |
---|
580 | &receive_flag, False, |
---|
581 | &vm_flag, False, |
---|
582 | NULL, NULL); |
---|
583 | |
---|
584 | units_options[2] = XtVaCreateManagedWidget( |
---|
585 | "cylinders", commandWidgetClass, ft_dialog, |
---|
586 | XtNfromVert, units_options[1], |
---|
587 | XtNvertDistance, CLOSE_VGAP, |
---|
588 | XtNfromHoriz, h_ref, |
---|
589 | XtNhorizDistance, COLUMN_GAP, |
---|
590 | XtNborderWidth, 0, |
---|
591 | NULL); |
---|
592 | apply_bitmap(units_options[2], |
---|
593 | (units == CYLINDERS) ? diamond : no_diamond); |
---|
594 | XtAddCallback(units_options[2], XtNcallback, |
---|
595 | units_callback, (XtPointer)&u_cylinders); |
---|
596 | register_sensitivity(units_options[2], |
---|
597 | &receive_flag, False, |
---|
598 | &vm_flag, False, |
---|
599 | NULL, NULL); |
---|
600 | |
---|
601 | units_options[3] = XtVaCreateManagedWidget( |
---|
602 | "avblock", commandWidgetClass, ft_dialog, |
---|
603 | XtNfromVert, units_options[2], |
---|
604 | XtNvertDistance, CLOSE_VGAP, |
---|
605 | XtNfromHoriz, h_ref, |
---|
606 | XtNhorizDistance, COLUMN_GAP, |
---|
607 | XtNborderWidth, 0, |
---|
608 | NULL); |
---|
609 | apply_bitmap(units_options[3], |
---|
610 | (units == AVBLOCK) ? diamond : no_diamond); |
---|
611 | XtAddCallback(units_options[3], XtNcallback, |
---|
612 | units_callback, (XtPointer)&u_avblock); |
---|
613 | register_sensitivity(units_options[3], |
---|
614 | &receive_flag, False, |
---|
615 | &vm_flag, False, |
---|
616 | NULL, NULL); |
---|
617 | |
---|
618 | primspace_label = XtVaCreateManagedWidget( |
---|
619 | "primspace", labelWidgetClass, ft_dialog, |
---|
620 | XtNfromVert, units_options[3], |
---|
621 | XtNvertDistance, 3, |
---|
622 | XtNfromHoriz, h_ref, |
---|
623 | XtNhorizDistance, COLUMN_GAP, |
---|
624 | XtNborderWidth, 0, |
---|
625 | NULL); |
---|
626 | register_sensitivity(primspace_label, |
---|
627 | &receive_flag, False, |
---|
628 | &vm_flag, False, |
---|
629 | &units_default, False); |
---|
630 | primspace_widget = XtVaCreateManagedWidget( |
---|
631 | "value", asciiTextWidgetClass, ft_dialog, |
---|
632 | XtNfromVert, units_options[3], |
---|
633 | XtNvertDistance, 3, |
---|
634 | XtNfromHoriz, primspace_label, |
---|
635 | XtNhorizDistance, 0, |
---|
636 | XtNwidth, 100, |
---|
637 | XtNeditType, XawtextEdit, |
---|
638 | XtNdisplayCaret, False, |
---|
639 | NULL); |
---|
640 | match_dimension(primspace_label, primspace_widget, XtNheight); |
---|
641 | w = XawTextGetSource(primspace_widget); |
---|
642 | if (w == NULL) |
---|
643 | XtWarning("Cannot find text source in dialog"); |
---|
644 | else |
---|
645 | XtAddCallback(w, XtNcallback, text_callback, |
---|
646 | (XtPointer)&t_numeric); |
---|
647 | register_sensitivity(primspace_widget, |
---|
648 | &receive_flag, False, |
---|
649 | &vm_flag, False, |
---|
650 | &units_default, False); |
---|
651 | |
---|
652 | secspace_label = XtVaCreateManagedWidget( |
---|
653 | "secspace", labelWidgetClass, ft_dialog, |
---|
654 | XtNfromVert, primspace_widget, |
---|
655 | XtNvertDistance, 3, |
---|
656 | XtNfromHoriz, h_ref, |
---|
657 | XtNhorizDistance, COLUMN_GAP, |
---|
658 | XtNborderWidth, 0, |
---|
659 | NULL); |
---|
660 | match_dimension(primspace_label, secspace_label, XtNwidth); |
---|
661 | register_sensitivity(secspace_label, |
---|
662 | &receive_flag, False, |
---|
663 | &vm_flag, False, |
---|
664 | &units_default, False); |
---|
665 | secspace_widget = XtVaCreateManagedWidget( |
---|
666 | "value", asciiTextWidgetClass, ft_dialog, |
---|
667 | XtNfromVert, primspace_widget, |
---|
668 | XtNvertDistance, 3, |
---|
669 | XtNfromHoriz, secspace_label, |
---|
670 | XtNhorizDistance, 0, |
---|
671 | XtNwidth, 100, |
---|
672 | XtNeditType, XawtextEdit, |
---|
673 | XtNdisplayCaret, False, |
---|
674 | NULL); |
---|
675 | match_dimension(secspace_label, secspace_widget, XtNheight); |
---|
676 | w = XawTextGetSource(secspace_widget); |
---|
677 | if (w == NULL) |
---|
678 | XtWarning("Cannot find text source in dialog"); |
---|
679 | else |
---|
680 | XtAddCallback(w, XtNcallback, text_callback, |
---|
681 | (XtPointer)&t_numeric); |
---|
682 | register_sensitivity(secspace_widget, |
---|
683 | &receive_flag, False, |
---|
684 | &vm_flag, False, |
---|
685 | &units_default, False); |
---|
686 | |
---|
687 | /* Set up the buttons at the bottom. */ |
---|
688 | start_button = XtVaCreateManagedWidget( |
---|
689 | ObjConfirmButton, commandWidgetClass, ft_dialog, |
---|
690 | XtNfromVert, blksize_label, |
---|
691 | XtNvertDistance, FAR_VGAP, |
---|
692 | XtNhorizDistance, MARGIN, |
---|
693 | NULL); |
---|
694 | XtAddCallback(start_button, XtNcallback, ft_start_callback, |
---|
695 | (XtPointer)NULL); |
---|
696 | |
---|
697 | cancel_button = XtVaCreateManagedWidget( |
---|
698 | ObjCancelButton, commandWidgetClass, ft_dialog, |
---|
699 | XtNfromVert, blksize_label, |
---|
700 | XtNvertDistance, FAR_VGAP, |
---|
701 | XtNfromHoriz, start_button, |
---|
702 | XtNhorizDistance, BUTTON_GAP, |
---|
703 | NULL); |
---|
704 | XtAddCallback(cancel_button, XtNcallback, ft_cancel, 0); |
---|
705 | } |
---|
706 | |
---|
707 | |
---|
708 | |
---|
709 | /* Callbacks for all the transfer widgets. */ |
---|
710 | |
---|
711 | /* Transfer pop-up popping up. */ |
---|
712 | static void |
---|
713 | ft_popup_callback(w, client_data, call_data) |
---|
714 | Widget w; |
---|
715 | XtPointer client_data; |
---|
716 | XtPointer call_data; |
---|
717 | { |
---|
718 | /* Set the focus to the local file widget. */ |
---|
719 | dialog_focus_action(local_file, (XEvent *)NULL, (String *)NULL, |
---|
720 | (Cardinal *)NULL); |
---|
721 | |
---|
722 | /* Disallow overwrites. */ |
---|
723 | allow_overwrite = False; |
---|
724 | } |
---|
725 | |
---|
726 | /* Cancel button pushed. */ |
---|
727 | static void |
---|
728 | ft_cancel(w, client_data, call_data) |
---|
729 | Widget w; |
---|
730 | XtPointer client_data; |
---|
731 | XtPointer call_data; |
---|
732 | { |
---|
733 | XtPopdown(ft_shell); |
---|
734 | } |
---|
735 | |
---|
736 | /* recfm options. */ |
---|
737 | static void |
---|
738 | recfm_callback(w, user_data, call_data) |
---|
739 | Widget w; |
---|
740 | XtPointer user_data; |
---|
741 | XtPointer call_data; |
---|
742 | { |
---|
743 | recfm = *(enum recfm *)user_data; |
---|
744 | recfm_default = (recfm == DEFAULT_RECFM); |
---|
745 | check_sensitivity(&recfm_default); |
---|
746 | flip_toggles(&recfm_toggles, w); |
---|
747 | } |
---|
748 | |
---|
749 | /* Units options. */ |
---|
750 | static void |
---|
751 | units_callback(w, user_data, call_data) |
---|
752 | Widget w; |
---|
753 | XtPointer user_data; |
---|
754 | XtPointer call_data; |
---|
755 | { |
---|
756 | units = *(enum units *)user_data; |
---|
757 | units_default = (units == DEFAULT_UNITS); |
---|
758 | check_sensitivity(&units_default); |
---|
759 | flip_toggles(&units_toggles, w); |
---|
760 | } |
---|
761 | |
---|
762 | /* OK button pushed. */ |
---|
763 | static void |
---|
764 | ft_start_callback(w, call_parms, call_data) |
---|
765 | Widget w; |
---|
766 | XtPointer call_parms; |
---|
767 | XtPointer call_data; |
---|
768 | { |
---|
769 | if (ft_start()) { |
---|
770 | XtPopdown(ft_shell); |
---|
771 | popup_progress(); |
---|
772 | } |
---|
773 | } |
---|
774 | |
---|
775 | /* Mark a toggle. */ |
---|
776 | static void |
---|
777 | mark_toggle(w, p) |
---|
778 | Widget w; |
---|
779 | Pixmap p; |
---|
780 | { |
---|
781 | #if defined(TOGGLE_HACK) /*[*/ |
---|
782 | String l, nl; |
---|
783 | |
---|
784 | XtVaGetValues(w, XtNlabel, &l, NULL); |
---|
785 | nl = XtNewString(l); |
---|
786 | if (p == diamond) |
---|
787 | nl[0] = '+'; |
---|
788 | else if (p == no_diamond) |
---|
789 | nl[0] = '-'; |
---|
790 | else if (p == dot) |
---|
791 | nl[0] = '*'; |
---|
792 | else if (p == null) |
---|
793 | nl[0] = ' '; |
---|
794 | XtVaSetValues(w, XtNlabel, nl, NULL); |
---|
795 | XtFree(nl); |
---|
796 | #else /*][*/ |
---|
797 | XtVaSetValues(w, XtNleftBitmap, p, NULL); |
---|
798 | #endif /*]*/ |
---|
799 | } |
---|
800 | |
---|
801 | /* Send/receive options. */ |
---|
802 | static void |
---|
803 | toggle_receive(w, client_data, call_data) |
---|
804 | Widget w; |
---|
805 | XtPointer client_data; |
---|
806 | XtPointer call_data; |
---|
807 | { |
---|
808 | /* Toggle the flag */ |
---|
809 | receive_flag = *(Boolean *)client_data; |
---|
810 | |
---|
811 | /* Change the widget states. */ |
---|
812 | mark_toggle(receive_toggle, receive_flag ? diamond : no_diamond); |
---|
813 | mark_toggle(send_toggle, receive_flag ? no_diamond : diamond); |
---|
814 | check_sensitivity(&receive_flag); |
---|
815 | } |
---|
816 | |
---|
817 | /* Ascii/binary options. */ |
---|
818 | static void |
---|
819 | toggle_ascii(w, client_data, call_data) |
---|
820 | Widget w; |
---|
821 | XtPointer client_data; |
---|
822 | XtPointer call_data; |
---|
823 | { |
---|
824 | /* Toggle the flag. */ |
---|
825 | ascii_flag = *(Boolean *)client_data; |
---|
826 | |
---|
827 | /* Change the widget states. */ |
---|
828 | mark_toggle(ascii_toggle, ascii_flag ? diamond : no_diamond); |
---|
829 | mark_toggle(binary_toggle, ascii_flag ? no_diamond : diamond); |
---|
830 | cr_flag = ascii_flag; |
---|
831 | mark_toggle(cr_widget, cr_flag ? dot : null); |
---|
832 | check_sensitivity(&ascii_flag); |
---|
833 | } |
---|
834 | |
---|
835 | /* CR option. */ |
---|
836 | static void |
---|
837 | toggle_cr(w, client_data, call_data) |
---|
838 | Widget w; |
---|
839 | XtPointer client_data; |
---|
840 | XtPointer call_data; |
---|
841 | { |
---|
842 | /* Toggle the cr flag */ |
---|
843 | cr_flag = !cr_flag; |
---|
844 | |
---|
845 | mark_toggle(w, cr_flag ? dot : null); |
---|
846 | } |
---|
847 | |
---|
848 | /* Append option. */ |
---|
849 | static void |
---|
850 | toggle_append(w, client_data, call_data) |
---|
851 | Widget w; |
---|
852 | XtPointer client_data; |
---|
853 | XtPointer call_data; |
---|
854 | { |
---|
855 | /* Toggle Append Flag */ |
---|
856 | append_flag = !append_flag; |
---|
857 | |
---|
858 | mark_toggle(w, append_flag ? dot : null); |
---|
859 | } |
---|
860 | |
---|
861 | /* TSO/VM option. */ |
---|
862 | static void |
---|
863 | toggle_vm(w, client_data, call_data) |
---|
864 | Widget w; |
---|
865 | XtPointer client_data; |
---|
866 | XtPointer call_data; |
---|
867 | { |
---|
868 | /* Toggle the flag. */ |
---|
869 | vm_flag = *(Boolean *)client_data; |
---|
870 | |
---|
871 | /* Change the widget states. */ |
---|
872 | mark_toggle(vm_toggle, vm_flag ? diamond : no_diamond); |
---|
873 | mark_toggle(tso_toggle, vm_flag ? no_diamond : diamond); |
---|
874 | |
---|
875 | if (vm_flag) { |
---|
876 | if (recfm == UNDEFINED) { |
---|
877 | recfm = DEFAULT_RECFM; |
---|
878 | recfm_default = True; |
---|
879 | flip_toggles(&recfm_toggles, |
---|
880 | recfm_toggles.widgets[0]); |
---|
881 | } |
---|
882 | } |
---|
883 | check_sensitivity(&vm_flag); |
---|
884 | } |
---|
885 | |
---|
886 | /* |
---|
887 | * Begin the transfer. |
---|
888 | * Returns 1 if the transfer has started, 0 otherwise. |
---|
889 | */ |
---|
890 | static int |
---|
891 | ft_start() |
---|
892 | { |
---|
893 | char opts[80]; |
---|
894 | char *op = opts + 1; |
---|
895 | char *cmd; |
---|
896 | String lrecl, blksize, primspace, secspace; |
---|
897 | int flen; |
---|
898 | char *host_filename; |
---|
899 | |
---|
900 | /* Get the host file from its widget */ |
---|
901 | XtVaGetValues(host_file, XtNstring, &host_filename, NULL); |
---|
902 | if (!*host_filename) |
---|
903 | return 0; |
---|
904 | /* XXX: probably more validation to do here */ |
---|
905 | |
---|
906 | /* Get the local file from it widget */ |
---|
907 | XtVaGetValues(local_file, XtNstring, &ft_local_filename, NULL); |
---|
908 | if (!*ft_local_filename) |
---|
909 | return 0; |
---|
910 | |
---|
911 | /* See if the local file can be overwritten. */ |
---|
912 | if (receive_flag && !append_flag && !allow_overwrite) { |
---|
913 | ft_local_file = fopen(ft_local_filename, "r"); |
---|
914 | if (ft_local_file != (FILE *)NULL) { |
---|
915 | (void) fclose(ft_local_file); |
---|
916 | ft_local_file = (FILE *)NULL; |
---|
917 | popup_overwrite(); |
---|
918 | return 0; |
---|
919 | } |
---|
920 | } |
---|
921 | |
---|
922 | /* Open the local file. */ |
---|
923 | ft_local_file = fopen(ft_local_filename, |
---|
924 | receive_flag ? |
---|
925 | (append_flag ? "a" : "w" ) : |
---|
926 | "r"); |
---|
927 | if (ft_local_file == (FILE *)NULL) { |
---|
928 | allow_overwrite = False; |
---|
929 | popup_an_errno(errno, "Open(%s)", ft_local_filename); |
---|
930 | return 0; |
---|
931 | } |
---|
932 | |
---|
933 | /* Build the ind$file command */ |
---|
934 | op[0] = '\0'; |
---|
935 | if (ascii_flag) |
---|
936 | strcat(op, " ascii"); |
---|
937 | if (cr_flag) |
---|
938 | strcat(op, " crlf"); |
---|
939 | if (append_flag && !receive_flag) |
---|
940 | strcat(op, " append"); |
---|
941 | if (!receive_flag) { |
---|
942 | if (!vm_flag) { |
---|
943 | if (recfm != DEFAULT_RECFM) { |
---|
944 | /* RECFM Entered, process */ |
---|
945 | strcat(op, " recfm("); |
---|
946 | switch (recfm) { |
---|
947 | case FIXED: |
---|
948 | strcat(op, "f"); |
---|
949 | break; |
---|
950 | case VARIABLE: |
---|
951 | strcat(op, "v"); |
---|
952 | break; |
---|
953 | case UNDEFINED: |
---|
954 | strcat(op, "u"); |
---|
955 | break; |
---|
956 | default: |
---|
957 | break; |
---|
958 | }; |
---|
959 | strcat(op, ")"); |
---|
960 | XtVaGetValues(lrecl_widget, |
---|
961 | XtNstring, &lrecl, |
---|
962 | NULL); |
---|
963 | if (strlen(lrecl) > 0) |
---|
964 | sprintf(eos(op), " lrecl(%s)", lrecl); |
---|
965 | XtVaGetValues(blksize_widget, |
---|
966 | XtNstring, &blksize, |
---|
967 | NULL); |
---|
968 | if (strlen(blksize) > 0) |
---|
969 | sprintf(eos(op), " blksize(%s)", |
---|
970 | blksize); |
---|
971 | } |
---|
972 | if (units != DEFAULT_UNITS) { |
---|
973 | /* Space Entered, processs it */ |
---|
974 | switch (units) { |
---|
975 | case TRACKS: |
---|
976 | strcat(op, " tracks"); |
---|
977 | break; |
---|
978 | case CYLINDERS: |
---|
979 | strcat(op, " cylinders"); |
---|
980 | break; |
---|
981 | case AVBLOCK: |
---|
982 | strcat(op, " avblock"); |
---|
983 | break; |
---|
984 | default: |
---|
985 | break; |
---|
986 | }; |
---|
987 | XtVaGetValues(primspace_widget, XtNstring, |
---|
988 | &primspace, NULL); |
---|
989 | if (strlen(primspace) > 0) { |
---|
990 | sprintf(eos(op), " space(%s", |
---|
991 | primspace); |
---|
992 | XtVaGetValues(secspace_widget, |
---|
993 | XtNstring, &secspace, |
---|
994 | NULL); |
---|
995 | if (strlen(secspace) > 0) |
---|
996 | sprintf(eos(op), ",%s", |
---|
997 | secspace); |
---|
998 | strcat(op, ")"); |
---|
999 | } |
---|
1000 | } |
---|
1001 | } else { |
---|
1002 | if (recfm != DEFAULT_RECFM) { |
---|
1003 | strcat(op, " recfm "); |
---|
1004 | switch (recfm) { |
---|
1005 | case FIXED: |
---|
1006 | strcat(op, "f"); |
---|
1007 | break; |
---|
1008 | case VARIABLE: |
---|
1009 | strcat(op, "v"); |
---|
1010 | break; |
---|
1011 | default: |
---|
1012 | break; |
---|
1013 | }; |
---|
1014 | |
---|
1015 | XtVaGetValues(lrecl_widget, |
---|
1016 | XtNstring, &lrecl, |
---|
1017 | NULL); |
---|
1018 | if (strlen(lrecl) > 0) |
---|
1019 | sprintf(eos(op), " lrecl %s", lrecl); |
---|
1020 | } |
---|
1021 | } |
---|
1022 | } |
---|
1023 | |
---|
1024 | /* Insert the '(' for VM options. */ |
---|
1025 | if (strlen(op) > 0 && vm_flag) { |
---|
1026 | opts[0] = ' '; |
---|
1027 | opts[1] = '('; |
---|
1028 | op = opts; |
---|
1029 | } |
---|
1030 | |
---|
1031 | /* Build the whole command. */ |
---|
1032 | cmd = xs_buffer("%s %s %s%s\\n", |
---|
1033 | appres.ft_command, |
---|
1034 | receive_flag ? "get" : "put", host_filename, op); |
---|
1035 | |
---|
1036 | /* Erase the line and enter the command. */ |
---|
1037 | flen = kybd_prime(); |
---|
1038 | if (!flen || flen < strlen(cmd) - 1) { |
---|
1039 | XtFree(cmd); |
---|
1040 | popup_an_error(get_message("ftUnable")); |
---|
1041 | allow_overwrite = False; |
---|
1042 | return 0; |
---|
1043 | } |
---|
1044 | (void) emulate_input(cmd, strlen(cmd), False); |
---|
1045 | XtFree(cmd); |
---|
1046 | |
---|
1047 | /* Get this thing started. */ |
---|
1048 | ft_state = FT_AWAIT_ACK; |
---|
1049 | ft_is_cut = False; |
---|
1050 | |
---|
1051 | return 1; |
---|
1052 | } |
---|
1053 | |
---|
1054 | /* "Transfer in Progress" pop-up. */ |
---|
1055 | |
---|
1056 | /* Pop up the "in progress" pop-up. */ |
---|
1057 | static void |
---|
1058 | popup_progress() |
---|
1059 | { |
---|
1060 | /* Initialize it. */ |
---|
1061 | if (progress_shell == (Widget)NULL) |
---|
1062 | progress_popup_init(); |
---|
1063 | |
---|
1064 | /* Pop it up. */ |
---|
1065 | popup_popup(progress_shell, XtGrabNone); |
---|
1066 | } |
---|
1067 | |
---|
1068 | /* Initialize the "in progress" pop-up. */ |
---|
1069 | static void |
---|
1070 | progress_popup_init() |
---|
1071 | { |
---|
1072 | Widget progress_pop, from_label, to_label, cancel_button; |
---|
1073 | |
---|
1074 | /* Create the shell. */ |
---|
1075 | progress_shell = XtVaCreatePopupShell( |
---|
1076 | "ftProgressPopup", transientShellWidgetClass, toplevel, |
---|
1077 | NULL); |
---|
1078 | XtAddCallback(progress_shell, XtNpopupCallback, place_popup, |
---|
1079 | (XtPointer)CenterP); |
---|
1080 | XtAddCallback(progress_shell, XtNpopupCallback, |
---|
1081 | progress_popup_callback, (XtPointer)NULL); |
---|
1082 | |
---|
1083 | /* Create a form structure to contain the other stuff */ |
---|
1084 | progress_pop = XtVaCreateManagedWidget( |
---|
1085 | "dialog", formWidgetClass, progress_shell, |
---|
1086 | NULL); |
---|
1087 | |
---|
1088 | /* Create the widgets. */ |
---|
1089 | from_label = XtVaCreateManagedWidget( |
---|
1090 | "fromLabel", labelWidgetClass, progress_pop, |
---|
1091 | XtNvertDistance, FAR_VGAP, |
---|
1092 | XtNhorizDistance, MARGIN, |
---|
1093 | XtNborderWidth, 0, |
---|
1094 | NULL); |
---|
1095 | from_file = XtVaCreateManagedWidget( |
---|
1096 | "filename", labelWidgetClass, progress_pop, |
---|
1097 | XtNwidth, FILE_WIDTH, |
---|
1098 | XtNvertDistance, FAR_VGAP, |
---|
1099 | XtNfromHoriz, from_label, |
---|
1100 | XtNhorizDistance, 0, |
---|
1101 | NULL); |
---|
1102 | match_dimension(from_label, from_file, XtNheight); |
---|
1103 | |
---|
1104 | to_label = XtVaCreateManagedWidget( |
---|
1105 | "toLabel", labelWidgetClass, progress_pop, |
---|
1106 | XtNfromVert, from_label, |
---|
1107 | XtNvertDistance, FAR_VGAP, |
---|
1108 | XtNhorizDistance, MARGIN, |
---|
1109 | XtNborderWidth, 0, |
---|
1110 | NULL); |
---|
1111 | to_file = XtVaCreateManagedWidget( |
---|
1112 | "filename", labelWidgetClass, progress_pop, |
---|
1113 | XtNwidth, FILE_WIDTH, |
---|
1114 | XtNfromVert, from_label, |
---|
1115 | XtNvertDistance, FAR_VGAP, |
---|
1116 | XtNfromHoriz, to_label, |
---|
1117 | XtNhorizDistance, 0, |
---|
1118 | NULL); |
---|
1119 | match_dimension(to_label, to_file, XtNheight); |
---|
1120 | |
---|
1121 | match_dimension(from_label, to_label, XtNwidth); |
---|
1122 | |
---|
1123 | waiting = XtVaCreateManagedWidget( |
---|
1124 | "waiting", labelWidgetClass, progress_pop, |
---|
1125 | XtNfromVert, to_label, |
---|
1126 | XtNvertDistance, FAR_VGAP, |
---|
1127 | XtNhorizDistance, MARGIN, |
---|
1128 | XtNborderWidth, 0, |
---|
1129 | XtNmappedWhenManaged, False, |
---|
1130 | NULL); |
---|
1131 | |
---|
1132 | ft_status = XtVaCreateManagedWidget( |
---|
1133 | "status", labelWidgetClass, progress_pop, |
---|
1134 | XtNfromVert, to_label, |
---|
1135 | XtNvertDistance, FAR_VGAP, |
---|
1136 | XtNhorizDistance, MARGIN, |
---|
1137 | XtNborderWidth, 0, |
---|
1138 | XtNresizable, True, |
---|
1139 | XtNmappedWhenManaged, False, |
---|
1140 | NULL); |
---|
1141 | XtVaGetValues(ft_status, XtNlabel, &status_string, NULL); |
---|
1142 | status_string = XtNewString(status_string); |
---|
1143 | |
---|
1144 | aborting = XtVaCreateManagedWidget( |
---|
1145 | "aborting", labelWidgetClass, progress_pop, |
---|
1146 | XtNfromVert, to_label, |
---|
1147 | XtNvertDistance, FAR_VGAP, |
---|
1148 | XtNhorizDistance, MARGIN, |
---|
1149 | XtNborderWidth, 0, |
---|
1150 | XtNmappedWhenManaged, False, |
---|
1151 | NULL); |
---|
1152 | |
---|
1153 | cancel_button = XtVaCreateManagedWidget( |
---|
1154 | ObjCancelButton, commandWidgetClass, progress_pop, |
---|
1155 | XtNfromVert, ft_status, |
---|
1156 | XtNvertDistance, FAR_VGAP, |
---|
1157 | XtNhorizDistance, MARGIN, |
---|
1158 | NULL); |
---|
1159 | XtAddCallback(cancel_button, XtNcallback, progress_cancel_callback, |
---|
1160 | NULL); |
---|
1161 | } |
---|
1162 | |
---|
1163 | /* Callbacks for the "in progress" pop-up. */ |
---|
1164 | |
---|
1165 | /* In-progress pop-up popped up. */ |
---|
1166 | static void |
---|
1167 | progress_popup_callback(w, client_data, call_data) |
---|
1168 | Widget w; |
---|
1169 | XtPointer client_data; |
---|
1170 | XtPointer call_data; |
---|
1171 | { |
---|
1172 | String hf, lf; |
---|
1173 | |
---|
1174 | XtVaGetValues(host_file, XtNstring, &hf, NULL); |
---|
1175 | XtVaGetValues(local_file, XtNstring, &lf, NULL); |
---|
1176 | |
---|
1177 | XtVaSetValues(from_file, XtNlabel, receive_flag ? hf : lf, NULL); |
---|
1178 | XtVaSetValues(to_file, XtNlabel, receive_flag ? lf : hf, NULL); |
---|
1179 | |
---|
1180 | switch (ft_state) { |
---|
1181 | case FT_AWAIT_ACK: |
---|
1182 | XtUnmapWidget(ft_status); |
---|
1183 | XtUnmapWidget(aborting); |
---|
1184 | XtMapWidget(waiting); |
---|
1185 | break; |
---|
1186 | case FT_RUNNING: |
---|
1187 | XtUnmapWidget(waiting); |
---|
1188 | XtUnmapWidget(aborting); |
---|
1189 | XtMapWidget(ft_status); |
---|
1190 | break; |
---|
1191 | case FT_ABORT_WAIT: |
---|
1192 | case FT_ABORT_SENT: |
---|
1193 | XtUnmapWidget(waiting); |
---|
1194 | XtUnmapWidget(ft_status); |
---|
1195 | XtMapWidget(aborting); |
---|
1196 | break; |
---|
1197 | default: |
---|
1198 | break; |
---|
1199 | } |
---|
1200 | } |
---|
1201 | |
---|
1202 | /* In-progress "cancel" button. */ |
---|
1203 | static void |
---|
1204 | progress_cancel_callback(w, client_data, call_data) |
---|
1205 | Widget w; |
---|
1206 | XtPointer client_data; |
---|
1207 | XtPointer call_data; |
---|
1208 | { |
---|
1209 | if (ft_state == FT_RUNNING) { |
---|
1210 | ft_state = FT_ABORT_WAIT; |
---|
1211 | XtUnmapWidget(waiting); |
---|
1212 | XtUnmapWidget(ft_status); |
---|
1213 | XtMapWidget(aborting); |
---|
1214 | } else { |
---|
1215 | /* Impatient user or hung host -- just clean up. */ |
---|
1216 | ft_complete(get_message("ftUserCancel")); |
---|
1217 | } |
---|
1218 | } |
---|
1219 | |
---|
1220 | /* "Overwrite existing?" pop-up. */ |
---|
1221 | |
---|
1222 | /* Pop up the "overwrite" pop-up. */ |
---|
1223 | static void |
---|
1224 | popup_overwrite() |
---|
1225 | { |
---|
1226 | /* Initialize it. */ |
---|
1227 | if (overwrite_shell == (Widget)NULL) |
---|
1228 | overwrite_popup_init(); |
---|
1229 | |
---|
1230 | /* Pop it up. */ |
---|
1231 | popup_popup(overwrite_shell, XtGrabExclusive); |
---|
1232 | } |
---|
1233 | |
---|
1234 | /* Initialize the "overwrite" pop-up. */ |
---|
1235 | static void |
---|
1236 | overwrite_popup_init() |
---|
1237 | { |
---|
1238 | Widget overwrite_pop, overwrite_name, okay_button, cancel_button; |
---|
1239 | String overwrite_string, label, lf; |
---|
1240 | Dimension d; |
---|
1241 | |
---|
1242 | /* Create the shell. */ |
---|
1243 | overwrite_shell = XtVaCreatePopupShell( |
---|
1244 | "ftOverwritePopup", transientShellWidgetClass, toplevel, |
---|
1245 | NULL); |
---|
1246 | XtAddCallback(overwrite_shell, XtNpopupCallback, place_popup, |
---|
1247 | (XtPointer)CenterP); |
---|
1248 | XtAddCallback(overwrite_shell, XtNpopdownCallback, overwrite_popdown, |
---|
1249 | (XtPointer)NULL); |
---|
1250 | |
---|
1251 | /* Create a form structure to contain the other stuff */ |
---|
1252 | overwrite_pop = XtVaCreateManagedWidget( |
---|
1253 | "dialog", formWidgetClass, overwrite_shell, |
---|
1254 | NULL); |
---|
1255 | |
---|
1256 | /* Create the widgets. */ |
---|
1257 | overwrite_name = XtVaCreateManagedWidget( |
---|
1258 | "overwriteName", labelWidgetClass, overwrite_pop, |
---|
1259 | XtNvertDistance, MARGIN, |
---|
1260 | XtNhorizDistance, MARGIN, |
---|
1261 | XtNborderWidth, 0, |
---|
1262 | XtNresizable, True, |
---|
1263 | NULL); |
---|
1264 | XtVaGetValues(overwrite_name, XtNlabel, &overwrite_string, NULL); |
---|
1265 | XtVaGetValues(local_file, XtNstring, &lf, NULL); |
---|
1266 | label = xs_buffer(overwrite_string, lf); |
---|
1267 | XtVaSetValues(overwrite_name, XtNlabel, label, NULL); |
---|
1268 | XtFree(label); |
---|
1269 | XtVaGetValues(overwrite_name, XtNwidth, &d, NULL); |
---|
1270 | if ((Dimension)(d + 20) < 400) |
---|
1271 | d = 400; |
---|
1272 | else |
---|
1273 | d += 20; |
---|
1274 | XtVaSetValues(overwrite_name, XtNwidth, d, NULL); |
---|
1275 | XtVaGetValues(overwrite_name, XtNheight, &d, NULL); |
---|
1276 | XtVaSetValues(overwrite_name, XtNheight, d + 10, NULL); |
---|
1277 | |
---|
1278 | okay_button = XtVaCreateManagedWidget( |
---|
1279 | ObjConfirmButton, commandWidgetClass, overwrite_pop, |
---|
1280 | XtNfromVert, overwrite_name, |
---|
1281 | XtNvertDistance, FAR_VGAP, |
---|
1282 | XtNhorizDistance, MARGIN, |
---|
1283 | NULL); |
---|
1284 | XtAddCallback(okay_button, XtNcallback, overwrite_okay_callback, |
---|
1285 | NULL); |
---|
1286 | |
---|
1287 | cancel_button = XtVaCreateManagedWidget( |
---|
1288 | ObjCancelButton, commandWidgetClass, overwrite_pop, |
---|
1289 | XtNfromVert, overwrite_name, |
---|
1290 | XtNvertDistance, FAR_VGAP, |
---|
1291 | XtNfromHoriz, okay_button, |
---|
1292 | XtNhorizDistance, BUTTON_GAP, |
---|
1293 | NULL); |
---|
1294 | XtAddCallback(cancel_button, XtNcallback, overwrite_cancel_callback, |
---|
1295 | NULL); |
---|
1296 | } |
---|
1297 | |
---|
1298 | /* Overwrite "okay" button. */ |
---|
1299 | static void |
---|
1300 | overwrite_okay_callback(w, client_data, call_data) |
---|
1301 | Widget w; |
---|
1302 | XtPointer client_data; |
---|
1303 | XtPointer call_data; |
---|
1304 | { |
---|
1305 | XtPopdown(overwrite_shell); |
---|
1306 | |
---|
1307 | allow_overwrite = True; |
---|
1308 | if (ft_start()) { |
---|
1309 | XtPopdown(ft_shell); |
---|
1310 | popup_progress(); |
---|
1311 | } |
---|
1312 | } |
---|
1313 | |
---|
1314 | /* Overwrite "cancel" button. */ |
---|
1315 | static void |
---|
1316 | overwrite_cancel_callback(w, client_data, call_data) |
---|
1317 | Widget w; |
---|
1318 | XtPointer client_data; |
---|
1319 | XtPointer call_data; |
---|
1320 | { |
---|
1321 | XtPopdown(overwrite_shell); |
---|
1322 | } |
---|
1323 | |
---|
1324 | /* Overwrite pop-up popped down. */ |
---|
1325 | static void |
---|
1326 | overwrite_popdown(w, client_data, call_data) |
---|
1327 | Widget w; |
---|
1328 | XtPointer client_data; |
---|
1329 | XtPointer call_data; |
---|
1330 | { |
---|
1331 | XtDestroyWidget(overwrite_shell); |
---|
1332 | overwrite_shell = (Widget)NULL; |
---|
1333 | } |
---|
1334 | |
---|
1335 | /* External entry points called by ft_dft and ft_cut. */ |
---|
1336 | |
---|
1337 | /* Pop up a message, end the transfer. */ |
---|
1338 | void |
---|
1339 | ft_complete(errmsg) |
---|
1340 | String errmsg; |
---|
1341 | { |
---|
1342 | /* Close the local file. */ |
---|
1343 | if (ft_local_file != (FILE *)NULL && fclose(ft_local_file) < 0) |
---|
1344 | popup_an_errno(errno, "close(%s)", ft_local_filename); |
---|
1345 | ft_local_file = (FILE *)NULL; |
---|
1346 | |
---|
1347 | /* Clean up the state. */ |
---|
1348 | ft_state = FT_NONE; |
---|
1349 | |
---|
1350 | /* Pop down the in-progress shell. */ |
---|
1351 | XtPopdown(progress_shell); |
---|
1352 | |
---|
1353 | /* Pop up the text. */ |
---|
1354 | if (errmsg != (String)NULL) { |
---|
1355 | /* Make sure the error message will fit on the display. */ |
---|
1356 | if (strlen(errmsg) > 50 && strchr(errmsg, '\n') == CN) { |
---|
1357 | char *s = errmsg + 50; |
---|
1358 | |
---|
1359 | while (s > errmsg && *s != ' ') |
---|
1360 | s--; |
---|
1361 | if (s > errmsg) |
---|
1362 | *s = '\n'; |
---|
1363 | } |
---|
1364 | popup_an_error(errmsg); |
---|
1365 | XtFree(errmsg); |
---|
1366 | } else { |
---|
1367 | struct timeval t1; |
---|
1368 | double kbytes_sec; |
---|
1369 | char *buf; |
---|
1370 | |
---|
1371 | (void) gettimeofday(&t1, (struct timezone *)NULL); |
---|
1372 | kbytes_sec = (double)ft_length / 1024.0 / |
---|
1373 | ((double)(t1.tv_sec - t0.tv_sec) + |
---|
1374 | (double)(t1.tv_usec - t0.tv_usec) / 1.0e6); |
---|
1375 | buf = XtMalloc(256); |
---|
1376 | (void) sprintf(buf, get_message("ftComplete"), ft_length, |
---|
1377 | kbytes_sec, ft_is_cut ? "CUT" : "DFT"); |
---|
1378 | popup_an_info(buf); |
---|
1379 | XtFree(buf); |
---|
1380 | } |
---|
1381 | } |
---|
1382 | |
---|
1383 | /* Update the bytes-transferred count on the progress pop-up. */ |
---|
1384 | void |
---|
1385 | ft_update_length() |
---|
1386 | { |
---|
1387 | char text_string[80]; |
---|
1388 | |
---|
1389 | /* Format the message */ |
---|
1390 | sprintf(text_string, status_string, ft_length); |
---|
1391 | |
---|
1392 | XtVaSetValues(ft_status, XtNlabel, text_string, NULL); |
---|
1393 | } |
---|
1394 | |
---|
1395 | /* Process a transfer acknowledgement. */ |
---|
1396 | void |
---|
1397 | ft_running(is_cut) |
---|
1398 | Boolean is_cut; |
---|
1399 | { |
---|
1400 | if (ft_state == FT_AWAIT_ACK) |
---|
1401 | ft_state = FT_RUNNING; |
---|
1402 | ft_is_cut = is_cut; |
---|
1403 | (void) gettimeofday(&t0, (struct timezone *)NULL); |
---|
1404 | ft_length = 0; |
---|
1405 | |
---|
1406 | XtUnmapWidget(waiting); |
---|
1407 | ft_update_length(); |
---|
1408 | XtMapWidget(ft_status); |
---|
1409 | } |
---|
1410 | |
---|
1411 | /* Process a protocol-generated abort. */ |
---|
1412 | void |
---|
1413 | ft_aborting() |
---|
1414 | { |
---|
1415 | if (ft_state == FT_RUNNING || ft_state == FT_ABORT_WAIT) { |
---|
1416 | ft_state = FT_ABORT_SENT; |
---|
1417 | XtUnmapWidget(waiting); |
---|
1418 | XtUnmapWidget(ft_status); |
---|
1419 | XtMapWidget(aborting); |
---|
1420 | } |
---|
1421 | } |
---|
1422 | |
---|
1423 | /* Process a disconnect abort. */ |
---|
1424 | void |
---|
1425 | ft_disconnected() |
---|
1426 | { |
---|
1427 | if (ft_state != FT_NONE) |
---|
1428 | ft_complete(get_message("ftDisconnected")); |
---|
1429 | } |
---|
1430 | |
---|
1431 | /* Process an abort from no longer being in 3270 mode. */ |
---|
1432 | void |
---|
1433 | ft_not3270() |
---|
1434 | { |
---|
1435 | if (ft_state != FT_NONE) |
---|
1436 | ft_complete(get_message("ftNot3270")); |
---|
1437 | } |
---|
1438 | |
---|
1439 | /* Support functions for dialogs. */ |
---|
1440 | |
---|
1441 | /* Match one dimension of two widgets. */ |
---|
1442 | static void |
---|
1443 | match_dimension(w1, w2, n) |
---|
1444 | Widget w1; |
---|
1445 | Widget w2; |
---|
1446 | String n; |
---|
1447 | { |
---|
1448 | Dimension h1, h2; |
---|
1449 | Dimension b1, b2; |
---|
1450 | |
---|
1451 | XtVaGetValues(w1, n, &h1, XtNborderWidth, &b1, NULL); |
---|
1452 | XtVaGetValues(w2, n, &h2, XtNborderWidth, &b2, NULL); |
---|
1453 | h1 += 2 * b1; |
---|
1454 | h2 += 2 * b2; |
---|
1455 | if (h1 > h2) |
---|
1456 | XtVaSetValues(w2, n, h1 - (2 * b2), NULL); |
---|
1457 | else if (h2 > h1) |
---|
1458 | XtVaSetValues(w1, n, h2 - (2 * b1), NULL); |
---|
1459 | } |
---|
1460 | |
---|
1461 | /* Apply a bitmap to a widget. */ |
---|
1462 | static void |
---|
1463 | apply_bitmap(w, p) |
---|
1464 | Widget w; |
---|
1465 | Pixmap p; |
---|
1466 | { |
---|
1467 | Dimension d1; |
---|
1468 | #if defined(TOGGLE_HACK) /*[*/ |
---|
1469 | String l, nl; |
---|
1470 | #endif /*]*/ |
---|
1471 | |
---|
1472 | XtVaGetValues(w, XtNheight, &d1, NULL); |
---|
1473 | if (d1 < 10) |
---|
1474 | XtVaSetValues(w, XtNheight, 10, NULL); |
---|
1475 | #if defined(TOGGLE_HACK) /*[*/ |
---|
1476 | XtVaGetValues(w, XtNlabel, &l, NULL); |
---|
1477 | nl = XtMalloc(strlen(l) + 6); |
---|
1478 | if (p == diamond) |
---|
1479 | (void) sprintf(nl, "+ %s", l); |
---|
1480 | else if (p == dot) |
---|
1481 | (void) sprintf(nl, "* %s", l); |
---|
1482 | else if (p == no_diamond) |
---|
1483 | (void) sprintf(nl, "- %s", l); |
---|
1484 | else if (p == null) |
---|
1485 | (void) sprintf(nl, " %s", l); |
---|
1486 | XtVaSetValues(w, |
---|
1487 | XtNlabel, nl, |
---|
1488 | NULL); |
---|
1489 | XtFree(nl); |
---|
1490 | #else /*][*/ |
---|
1491 | XtVaSetValues(w, XtNleftBitmap, p, NULL); |
---|
1492 | #endif /*]*/ |
---|
1493 | } |
---|
1494 | |
---|
1495 | /* Flip a multi-valued toggle. */ |
---|
1496 | static void |
---|
1497 | flip_toggles(toggle_list, w) |
---|
1498 | struct toggle_list *toggle_list; |
---|
1499 | Widget w; |
---|
1500 | { |
---|
1501 | int i; |
---|
1502 | |
---|
1503 | /* Flip the widget w to on, and the rest to off. */ |
---|
1504 | for (i = 0; toggle_list->widgets[i] != (Widget)NULL; i++) { |
---|
1505 | /* Process each widget in the list */ |
---|
1506 | mark_toggle(*(toggle_list->widgets+i), |
---|
1507 | (*(toggle_list->widgets+i) == w) ? diamond : no_diamond); |
---|
1508 | } |
---|
1509 | } |
---|
1510 | |
---|
1511 | /* |
---|
1512 | * Callback for text source changes. Edits the text to ensure it meets the |
---|
1513 | * specified criteria. |
---|
1514 | */ |
---|
1515 | static void |
---|
1516 | text_callback(w, client_data, call_data) |
---|
1517 | Widget w; |
---|
1518 | XtPointer client_data; |
---|
1519 | XtPointer call_data; |
---|
1520 | { |
---|
1521 | XawTextBlock b; /* firstPos, length, ptr, format */ |
---|
1522 | static XawTextBlock nullb = { 0, 0, NULL }; |
---|
1523 | XawTextPosition pos = 0; |
---|
1524 | int i; |
---|
1525 | text_t t = *(text_t *)client_data; |
---|
1526 | static Boolean called_back = False; |
---|
1527 | |
---|
1528 | if (called_back) |
---|
1529 | return; |
---|
1530 | else |
---|
1531 | called_back = True; |
---|
1532 | |
---|
1533 | while (1) { |
---|
1534 | Boolean replaced = False; |
---|
1535 | |
---|
1536 | XawTextSourceRead(w, pos, &b, 1024); |
---|
1537 | if (b.length <= 0) |
---|
1538 | break; |
---|
1539 | nullb.format = b.format; |
---|
1540 | for (i = 0; i < b.length; i++) { |
---|
1541 | Boolean bad = False; |
---|
1542 | char c = *(b.ptr + i); |
---|
1543 | |
---|
1544 | switch (t) { |
---|
1545 | case T_NUMERIC: |
---|
1546 | /* Only numbers. */ |
---|
1547 | bad = !isdigit(c); |
---|
1548 | break; |
---|
1549 | case T_HOSTFILE: |
---|
1550 | /* |
---|
1551 | * Only printing characters and spaces; no |
---|
1552 | * leading or trailing blanks. |
---|
1553 | */ |
---|
1554 | bad = !isprint(c) || (!pos && !i && c == ' '); |
---|
1555 | break; |
---|
1556 | case T_UNIXFILE: |
---|
1557 | /* Only printing characters. */ |
---|
1558 | bad = !isgraph(c); |
---|
1559 | break; |
---|
1560 | } |
---|
1561 | if (bad) { |
---|
1562 | XawTextSourceReplace(w, pos + i, pos + i + 1, |
---|
1563 | &nullb); |
---|
1564 | pos = 0; |
---|
1565 | replaced = True; |
---|
1566 | break; |
---|
1567 | } |
---|
1568 | } |
---|
1569 | if (replaced) |
---|
1570 | continue; /* rescan the same block */ |
---|
1571 | pos += b.length; |
---|
1572 | if (b.length < 1024) |
---|
1573 | break; |
---|
1574 | } |
---|
1575 | called_back = False; |
---|
1576 | } |
---|
1577 | |
---|
1578 | /* Register widget sensitivity, based on zero to three Booleans. */ |
---|
1579 | static void |
---|
1580 | register_sensitivity(w, bvar1, bval1, bvar2, bval2, bvar3, bval3) |
---|
1581 | Widget w; |
---|
1582 | Boolean *bvar1; |
---|
1583 | Boolean bval1; |
---|
1584 | Boolean *bvar2; |
---|
1585 | Boolean bval2; |
---|
1586 | Boolean *bvar3; |
---|
1587 | Boolean bval3; |
---|
1588 | { |
---|
1589 | sr_t *s; |
---|
1590 | Boolean f; |
---|
1591 | |
---|
1592 | /* Allocate a structure. */ |
---|
1593 | s = (sr_t *)XtMalloc(sizeof(sr_t)); |
---|
1594 | s->w = w; |
---|
1595 | s->bvar1 = bvar1; |
---|
1596 | s->bval1 = bval1; |
---|
1597 | s->bvar2 = bvar2; |
---|
1598 | s->bval2 = bval2; |
---|
1599 | s->bvar3 = bvar3; |
---|
1600 | s->bval3 = bval3; |
---|
1601 | s->is_value = !strcmp(XtName(w), "value"); |
---|
1602 | s->has_focus = False; |
---|
1603 | |
---|
1604 | /* Link it onto the chain. */ |
---|
1605 | s->next = (sr_t *)NULL; |
---|
1606 | if (sr_last != (sr_t *)NULL) |
---|
1607 | sr_last->next = s; |
---|
1608 | else |
---|
1609 | sr = s; |
---|
1610 | sr_last = s; |
---|
1611 | |
---|
1612 | /* Set up the initial widget sensitivity. */ |
---|
1613 | if (bvar1 == (Boolean *)NULL) |
---|
1614 | f = True; |
---|
1615 | else { |
---|
1616 | f = (*bvar1 == bval1); |
---|
1617 | if (bvar2 != (Boolean *)NULL) |
---|
1618 | f &= (*bvar2 == bval2); |
---|
1619 | if (bvar3 != (Boolean *)NULL) |
---|
1620 | f &= (*bvar3 == bval3); |
---|
1621 | } |
---|
1622 | XtVaSetValues(w, XtNsensitive, f, NULL); |
---|
1623 | } |
---|
1624 | |
---|
1625 | /* Scan the list of registered widgets for a sensitivity change. */ |
---|
1626 | static void |
---|
1627 | check_sensitivity(bvar) |
---|
1628 | Boolean *bvar; |
---|
1629 | { |
---|
1630 | sr_t *s; |
---|
1631 | |
---|
1632 | for (s = sr; s != (sr_t *)NULL; s = s->next) { |
---|
1633 | if (s->bvar1 == bvar || s->bvar2 == bvar || s->bvar3 == bvar) { |
---|
1634 | Boolean f; |
---|
1635 | |
---|
1636 | f = (s->bvar1 != (Boolean *)NULL && |
---|
1637 | (*s->bvar1 == s->bval1)); |
---|
1638 | if (s->bvar2 != (Boolean *)NULL) |
---|
1639 | f &= (*s->bvar2 == s->bval2); |
---|
1640 | if (s->bvar3 != (Boolean *)NULL) |
---|
1641 | f &= (*s->bvar3 == s->bval3); |
---|
1642 | XtVaSetValues(s->w, XtNsensitive, f, NULL); |
---|
1643 | |
---|
1644 | /* If it is now insensitive, move the focus. */ |
---|
1645 | if (!f && s->is_value && s->has_focus) |
---|
1646 | focus_next(s); |
---|
1647 | } |
---|
1648 | } |
---|
1649 | } |
---|
1650 | |
---|
1651 | /* Move the input focus to the next sensitive value field. */ |
---|
1652 | static void |
---|
1653 | focus_next(s) |
---|
1654 | sr_t *s; |
---|
1655 | { |
---|
1656 | sr_t *t; |
---|
1657 | Boolean sen; |
---|
1658 | |
---|
1659 | /* Defocus this widget. */ |
---|
1660 | s->has_focus = False; |
---|
1661 | XawTextDisplayCaret(s->w, False); |
---|
1662 | |
---|
1663 | /* Search after. */ |
---|
1664 | for (t = s->next; t != (sr_t *)NULL; t = t->next) { |
---|
1665 | if (t->is_value) { |
---|
1666 | XtVaGetValues(t->w, XtNsensitive, &sen, NULL); |
---|
1667 | if (sen) |
---|
1668 | break; |
---|
1669 | } |
---|
1670 | } |
---|
1671 | |
---|
1672 | /* Wrap and search before. */ |
---|
1673 | if (t == (sr_t *)NULL) |
---|
1674 | for (t = sr; t != s && t != (sr_t *)NULL; t = t->next) { |
---|
1675 | if (t->is_value) { |
---|
1676 | XtVaGetValues(t->w, XtNsensitive, &sen, NULL); |
---|
1677 | if (sen) |
---|
1678 | break; |
---|
1679 | } |
---|
1680 | } |
---|
1681 | |
---|
1682 | /* Move the focus. */ |
---|
1683 | if (t != (sr_t *)NULL && t != s) { |
---|
1684 | t->has_focus = True; |
---|
1685 | XawTextDisplayCaret(t->w, True); |
---|
1686 | XtSetKeyboardFocus(ft_dialog, t->w); |
---|
1687 | } |
---|
1688 | } |
---|
1689 | |
---|
1690 | /* Dialog action procedures. */ |
---|
1691 | |
---|
1692 | /* Proceed to the next input field. */ |
---|
1693 | void |
---|
1694 | dialog_next_action(w, event, parms, num_parms) |
---|
1695 | Widget w; |
---|
1696 | XEvent *event; |
---|
1697 | String *parms; |
---|
1698 | Cardinal *num_parms; |
---|
1699 | { |
---|
1700 | sr_t *s; |
---|
1701 | |
---|
1702 | for (s = sr; s != (sr_t *)NULL; s = s->next) { |
---|
1703 | if (s->w == w) { |
---|
1704 | focus_next(s); |
---|
1705 | return; |
---|
1706 | } |
---|
1707 | } |
---|
1708 | } |
---|
1709 | |
---|
1710 | /* Set keyboard focus to an input field. */ |
---|
1711 | void |
---|
1712 | dialog_focus_action(w, event, parms, num_parms) |
---|
1713 | Widget w; |
---|
1714 | XEvent *event; |
---|
1715 | String *parms; |
---|
1716 | Cardinal *num_parms; |
---|
1717 | { |
---|
1718 | sr_t *s; |
---|
1719 | |
---|
1720 | /* Remove the focus from the widget that has it now. */ |
---|
1721 | for (s = sr; s != (sr_t *)NULL; s = s->next) { |
---|
1722 | if (s->has_focus) { |
---|
1723 | if (s->w == w) |
---|
1724 | return; |
---|
1725 | s->has_focus = False; |
---|
1726 | XawTextDisplayCaret(s->w, False); |
---|
1727 | break; |
---|
1728 | } |
---|
1729 | } |
---|
1730 | |
---|
1731 | /* Find this object. */ |
---|
1732 | for (s = sr; s != (sr_t *)NULL; s = s->next) { |
---|
1733 | if (s->w == w) |
---|
1734 | break; |
---|
1735 | } |
---|
1736 | if (s == (sr_t *)NULL) |
---|
1737 | return; |
---|
1738 | |
---|
1739 | /* Give it the focus. */ |
---|
1740 | s->has_focus = True; |
---|
1741 | XawTextDisplayCaret(w, True); |
---|
1742 | XtSetKeyboardFocus(ft_dialog, w); |
---|
1743 | } |
---|