1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <regex.h>
6 
7 #include <Xm/XmAll.h>
8 
9 #include "redtools.h"
10 
11 #if defined(HAVE_CONFIG_H)
12 #include "../config.h"
13 #endif
14 
15 #include "../macros.h"
16 
17 #include "redtool.h"
18 
19 
20 
red_initialize(void)21 __VISIBILITY_DEFAULT__ REDTOOLS red_initialize(void) {
22 	struct w_stk *w;
23 
24 	if((w = malloc(sizeof(struct w_stk))) == NULL) {
25 		(void) fprintf(
26 			stderr,
27 			_("Failed to allocate %lu bytes of memory: %s.%c"),
28 			(unsigned long) sizeof(struct w_stk), strerror(errno), CONFIG_LINE_FEED
29 		);
30 
31 		return(NULL);
32 	}
33 
34 	(void) memset((void *) w, 0, sizeof(struct w_stk));
35 
36 	w->head = NULL;
37 	w->title = NULL;
38 
39 	w->file_path = NULL;
40 	w->file_mask = NULL;
41 
42 	w->prompt_value = NULL;
43 
44 	w->dialog_buttons = NULL;
45 
46 	w->list_items = NULL;
47 	w->radio_items = NULL;
48 	w->button_items = NULL;
49 
50 	w->radio_preset = 0;
51 	w->button_preset = NULL;
52 
53 	(void) redtools_req_initialize(&w->w);
54 
55 	return((REDTOOLS) w);
56 }
57 
red_finalize(REDTOOLS h)58 __VISIBILITY_DEFAULT__ void red_finalize(REDTOOLS h) {
59 	struct w_stk *w;
60 
61 	if(h != NULL) {
62 		w = (struct w_stk *) h;
63 
64 		(void) redtools_req_finalize(&w->w);
65 		(void) free(h);
66 	}
67 }
68 
red_error_dialog(REDTOOLS h)69 __VISIBILITY_DEFAULT__ unsigned int red_error_dialog(REDTOOLS h) {
70 	return(rd_dialog_op(h, RED_DIALOG_ERROR));
71 }
72 
red_info_dialog(REDTOOLS h)73 __VISIBILITY_DEFAULT__ unsigned int red_info_dialog(REDTOOLS h) {
74 	return(rd_dialog_op(h, RED_DIALOG_INFO));
75 }
76 
red_message_dialog(REDTOOLS h)77 __VISIBILITY_DEFAULT__ unsigned int red_message_dialog(REDTOOLS h) {
78 	return(rd_dialog_op(h, RED_DIALOG_MESSAGE));
79 }
80 
red_question_dialog(REDTOOLS h)81 __VISIBILITY_DEFAULT__ unsigned int red_question_dialog(REDTOOLS h) {
82 	return(rd_dialog_op(h, RED_DIALOG_QUESTION));
83 }
84 
red_warning_dialog(REDTOOLS h)85 __VISIBILITY_DEFAULT__ unsigned int red_warning_dialog(REDTOOLS h) {
86 	return(rd_dialog_op(h, RED_DIALOG_WARNING));
87 }
88 
red_working_dialog(REDTOOLS h)89 __VISIBILITY_DEFAULT__ unsigned int red_working_dialog(REDTOOLS h) {
90 	return(rd_dialog_op(h, RED_DIALOG_WORKING));
91 }
92 
rd_dialog_op(REDTOOLS h,unsigned int g)93 static unsigned int rd_dialog_op(REDTOOLS h, unsigned int g) {
94 	unsigned int i, r;
95 
96 	struct d_par *p;
97 	struct w_stk *w;
98 
99 	if(h == NULL) return(0);
100 
101 	if((p = redtools_req_alloc()) == NULL) return(0);
102 
103 	w = (struct w_stk *) h;
104 
105 	p->class = RED_CLASS_DIALOG;
106 	p->item = g;
107 
108 	p->dialog.b_c = 0;
109 
110 	/* Set dialog title and buttons */
111 	(void) redtools_req_dialog_title_add(p, w->title);
112 
113 	if(w->dialog_buttons != NULL) {
114 		for(i = 0; ; i++) {
115 			if(w->dialog_buttons[i] == NULL) break;
116 
117 			(void) redtools_req_dialog_button_add(p, w->dialog_buttons[i]);
118 		}
119 	}
120 
121 	(void) redtools_req_open(&w->w, p);
122 
123 	/* Return what was selected */
124 	r = p->dialog.pressed;
125 
126 	(void) free(p);
127 
128 	return(r);
129 }
130 
red_dialog_add_title(REDTOOLS h,char * s)131 __VISIBILITY_DEFAULT__ void red_dialog_add_title(REDTOOLS h, char *s) {
132 	struct w_stk *w;
133 
134 	w = (struct w_stk *) h;
135 
136 	w->title = s;
137 }
138 
red_dialog_add_buttons(REDTOOLS h,char ** s)139 __VISIBILITY_DEFAULT__ void red_dialog_add_buttons(REDTOOLS h, char **s) {
140 	struct w_stk *w;
141 
142 	w = (struct w_stk *) h;
143 
144 	w->dialog_buttons = s;
145 }
146 
red_file(REDTOOLS h)147 __VISIBILITY_DEFAULT__ char *red_file(REDTOOLS h) {
148 	char *r;
149 
150 	struct d_par *p;
151 	struct w_stk *w;
152 
153 	if(h == NULL) return(NULL);
154 
155 	if((p = redtools_req_alloc()) == NULL) return(NULL);
156 
157 	w = (struct w_stk *) h;
158 
159 	p->class = RED_CLASS_FILE;
160 	p->item = 0;
161 
162 	/* Set default values */
163 	(void) redtools_req_file_title_add(p, w->head);
164 	(void) redtools_req_file_path_add(p, w->file_path);
165 	(void) redtools_req_file_mask_add(p, w->file_mask);
166 
167 	(void) redtools_req_open(&w->w, p);
168 
169 	/* Return what was selected */
170 	r = p->file.file;
171 
172 	(void) free(p);
173 
174 	return(r);
175 }
176 
red_file_free(char * s)177 __VISIBILITY_DEFAULT__ void red_file_free(char *s) {
178 	if(s != NULL) (void) XtFree(s);
179 }
180 
red_file_add_title(REDTOOLS h,char * e)181 __VISIBILITY_DEFAULT__ void red_file_add_title(REDTOOLS h, char *e) {
182 	struct w_stk *w;
183 
184 	w = (struct w_stk *) h;
185 
186 	w->head = e;
187 }
188 
red_file_add_path(REDTOOLS h,char * s)189 __VISIBILITY_DEFAULT__ void red_file_add_path(REDTOOLS h, char *s) {
190 	struct w_stk *w;
191 
192 	w = (struct w_stk *) h;
193 
194 	w->file_path = s;
195 }
196 
red_file_add_mask(REDTOOLS h,char * s)197 __VISIBILITY_DEFAULT__ void red_file_add_mask(REDTOOLS h, char *s) {
198 	struct w_stk *w;
199 
200 	w = (struct w_stk *) h;
201 
202 	w->file_mask = s;
203 }
204 
red_prompt(REDTOOLS h)205 __VISIBILITY_DEFAULT__ char *red_prompt(REDTOOLS h) {
206 	char *r;
207 
208 	struct d_par *p;
209 	struct w_stk *w;
210 
211 	if(h == NULL) return(NULL);
212 
213 	if((p = redtools_req_alloc()) == NULL) return(NULL);
214 
215 	w = (struct w_stk *) h;
216 
217 	p->class = RED_CLASS_PROMPT;
218 	p->item = 0;
219 
220 	/* Set dialog title and default value */
221 	(void) redtools_req_prompt_title_add(p, w->head, w->title);
222 	(void) redtools_req_prompt_value_add(p, w->prompt_value);
223 
224 	(void) redtools_req_open(&w->w, p);
225 
226 	/* Return what was selected */
227 	r = p->prompt.prompt;
228 
229 	(void) free(p);
230 
231 	return(r);
232 }
233 
red_prompt_free(char * s)234 __VISIBILITY_DEFAULT__ void red_prompt_free(char *s) {
235 	if(s != NULL) (void) XtFree(s);
236 }
237 
red_prompt_add_title(REDTOOLS h,char * e,char * s)238 __VISIBILITY_DEFAULT__ void red_prompt_add_title(REDTOOLS h, char *e, char *s) {
239 	struct w_stk *w;
240 
241 	w = (struct w_stk *) h;
242 
243 	w->head = e;
244 	w->title = s;
245 }
246 
red_prompt_add_value(REDTOOLS h,char * s)247 __VISIBILITY_DEFAULT__ void red_prompt_add_value(REDTOOLS h, char *s) {
248 	struct w_stk *w;
249 
250 	w = (struct w_stk *) h;
251 
252 	w->prompt_value = s;
253 }
254 
red_list(REDTOOLS h)255 __VISIBILITY_DEFAULT__ unsigned int *red_list(REDTOOLS h) {
256 	unsigned int i;
257 
258 	unsigned int *r;
259 
260 	struct d_par *p;
261 	struct w_stk *w;
262 
263 	if(h == NULL) return(NULL);
264 
265 	if((p = redtools_req_alloc()) == NULL) return(NULL);
266 
267 	w = (struct w_stk *) h;
268 
269 	p->class = RED_CLASS_LIST;
270 	p->item = 0;
271 
272 	p->list.i_c = 0;
273 	p->list.i_t = NULL;
274 
275 	/* Set dialog title and items */
276 	(void) redtools_req_list_title_add(p, w->head, w->title);
277 
278 	if(w->list_items != NULL) {
279 		for(i = 0; ; i++) {
280 			if(w->list_items[i] == NULL) break;
281 
282 			(void) redtools_req_list_item_add(p, w->list_items[i]);
283 		}
284 	}
285 
286 	(void) redtools_req_open(&w->w, p);
287 
288 	if(p->list.i_t != NULL) {
289 		for(i = 0; i < p->list.i_c; i++) {
290 			if(p->list.i_t[i] != NULL) (void) free(p->list.i_t[i]);
291 		}
292 
293 		(void) free(p->list.i_t);
294 	}
295 
296 	/* Return what was selected */
297 	r = p->list.list;
298 
299 	(void) free(p);
300 
301 	return(r);
302 }
303 
red_list_free(unsigned int * s)304 __VISIBILITY_DEFAULT__ void red_list_free(unsigned int *s) {
305 	if(s != NULL) (void) free(s);
306 }
307 
red_list_add_title(REDTOOLS h,char * e,char * s)308 __VISIBILITY_DEFAULT__ void red_list_add_title(REDTOOLS h, char *e, char *s) {
309 	struct w_stk *w;
310 
311 	w = (struct w_stk *) h;
312 
313 	w->head = e;
314 	w->title = s;
315 }
316 
red_list_add_items(REDTOOLS h,char ** s)317 __VISIBILITY_DEFAULT__ void red_list_add_items(REDTOOLS h, char **s) {
318 	struct w_stk *w;
319 
320 	w = (struct w_stk *) h;
321 
322 	w->list_items = s;
323 }
324 
red_radio(REDTOOLS h)325 __VISIBILITY_DEFAULT__ unsigned int red_radio(REDTOOLS h) {
326 	unsigned int i, r;
327 
328 	struct d_par *p;
329 	struct w_stk *w;
330 
331 	if(h == NULL) return(0);
332 
333 	if((p = redtools_req_alloc()) == NULL) return(0);
334 
335 	w = (struct w_stk *) h;
336 
337 	p->class = RED_CLASS_RADIO;
338 	p->item = 0;
339 
340 	p->radio.i_c = 0;
341 	p->radio.i_t = NULL;
342 
343 	/* Set dialog title and items */
344 	(void) redtools_req_radio_title_add(p, w->head, w->title);
345 
346 	if(w->radio_items != NULL) {
347 		for(i = 0; ; i++) {
348 			if(w->radio_items[i] == NULL) break;
349 
350 			(void) redtools_req_radio_item_add(p, w->radio_items[i]);
351 		}
352 	}
353 
354 	(void) redtools_req_radio_preset_add(p, w->radio_preset);
355 	(void) redtools_req_open(&w->w, p);
356 
357 	if(p->radio.i_t != NULL) {
358 		for(i = 0; i < p->radio.i_c; i++) {
359 			if(p->radio.i_t[i] != NULL) (void) free(p->radio.i_t[i]);
360 		}
361 
362 		(void) free(p->radio.i_t);
363 	}
364 
365 	/* Return what was selected */
366 	r = p->radio.button;
367 
368 	(void) free(p);
369 
370 	return(r);
371 }
372 
red_radio_add_title(REDTOOLS h,char * e,char * s)373 __VISIBILITY_DEFAULT__ void red_radio_add_title(REDTOOLS h, char *e, char *s) {
374 	struct w_stk *w;
375 
376 	w = (struct w_stk *) h;
377 
378 	w->head = e;
379 	w->title = s;
380 }
381 
red_radio_add_items(REDTOOLS h,char ** s)382 __VISIBILITY_DEFAULT__ void red_radio_add_items(REDTOOLS h, char **s) {
383 	struct w_stk *w;
384 
385 	w = (struct w_stk *) h;
386 
387 	w->radio_items = s;
388 }
389 
red_radio_add_preset(REDTOOLS h,unsigned int n)390 __VISIBILITY_DEFAULT__ void red_radio_add_preset(REDTOOLS h, unsigned int n) {
391 	struct w_stk *w;
392 
393 	w = (struct w_stk *) h;
394 
395 	w->radio_preset = n;
396 }
397 
red_button(REDTOOLS h)398 __VISIBILITY_DEFAULT__ unsigned int *red_button(REDTOOLS h) {
399 	unsigned int i;
400 
401 	unsigned int *r;
402 
403 	struct d_par *p;
404 	struct w_stk *w;
405 
406 	if(h == NULL) return(NULL);
407 
408 	if((p = redtools_req_alloc()) == NULL) return(NULL);
409 
410 	w = (struct w_stk *) h;
411 
412 	p->class = RED_CLASS_BUTTON;
413 	p->item = 0;
414 
415 	p->button.i_c = 0;
416 	p->button.i_t = NULL;
417 
418 	/* Set dialog title and items */
419 	(void) redtools_req_button_title_add(p, w->head, w->title);
420 
421 	if(w->button_items != NULL) {
422 		for(i = 0; ; i++) {
423 			if(w->button_items[i] == NULL) break;
424 
425 			(void) redtools_req_button_item_add(p, w->button_items[i]);
426 		}
427 	}
428 
429 	(void) redtools_req_button_preset_add(p, w->button_preset);
430 
431 	(void) redtools_req_open(&w->w, p);
432 
433 	if(p->button.i_t != NULL) {
434 		for(i = 0; i < p->button.i_c; i++) {
435 			if(p->button.i_t[i] != NULL) (void) free(p->button.i_t[i]);
436 		}
437 
438 		(void) free(p->button.i_t);
439 	}
440 
441 	/* Return what was selected */
442 	r = p->button.button;
443 
444 	(void) free(p);
445 
446 	return(r);
447 }
448 
red_button_free(unsigned int * s)449 __VISIBILITY_DEFAULT__ void red_button_free(unsigned int *s) {
450 	if(s != NULL) (void) free(s);
451 }
452 
red_button_add_title(REDTOOLS h,char * e,char * s)453 __VISIBILITY_DEFAULT__ void red_button_add_title(REDTOOLS h, char *e, char *s) {
454 	struct w_stk *w;
455 
456 	w = (struct w_stk *) h;
457 
458 	w->head = e;
459 	w->title = s;
460 }
461 
red_button_add_items(REDTOOLS h,char ** s)462 __VISIBILITY_DEFAULT__ void red_button_add_items(REDTOOLS h, char **s) {
463 	struct w_stk *w;
464 
465 	w = (struct w_stk *) h;
466 
467 	w->button_items = s;
468 }
469 
red_button_add_preset(REDTOOLS h,unsigned int * n)470 __VISIBILITY_DEFAULT__ void red_button_add_preset(REDTOOLS h, unsigned int *n) {
471 	struct w_stk *w;
472 
473 	w = (struct w_stk *) h;
474 
475 	w->button_preset = n;
476 }
477 
478 
479 
redtools_req_alloc(void)480 static struct d_par *redtools_req_alloc(void) {
481 	struct d_par *p;
482 
483 	if((p = malloc(sizeof(struct d_par))) == NULL) {
484 		(void) fprintf(
485 			stderr,
486 			_("Failed to allocate %lu bytes of memory: %s.%c"),
487 			(unsigned long) sizeof(struct d_par), strerror(errno), CONFIG_LINE_FEED
488 		);
489 
490 		return(NULL);
491 	}
492 
493 	(void) memset((void *) p, 0, sizeof(struct d_par));
494 
495 	return(p);
496 }
497 
redtools_req_dialog_op(Widget w,struct d_par * p)498 static void redtools_req_dialog_op(Widget w, struct d_par *p) {
499 	unsigned int i;
500 	int n;
501 
502 	Arg a[4];
503 	Widget d;
504 	XmString m;
505 
506 	m = XmStringCreateLocalized(p->dialog.b_t.s);
507 
508 	n = 0;
509 
510 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
511 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
512 	(void) XtSetArg(a[n], XmNoverrideRedirect, True); n++;
513 	(void) XtSetArg(a[n], XmNmessageString, m); n++;
514 
515 	switch(p->item) {
516 		case RED_DIALOG_ERROR:
517 			d = XmCreateErrorDialog(w, "Error", a, n);
518 
519 			break;
520 		case RED_DIALOG_INFO:
521 			d = XmCreateInformationDialog(w, "Information", a, n);
522 
523 			break;
524 		case RED_DIALOG_MESSAGE:
525 			d = XmCreateMessageDialog(w, "Message", a, n);
526 
527 			break;
528 		case RED_DIALOG_QUESTION:
529 			d = XmCreateQuestionDialog(w, "Question", a, n);
530 
531 			break;
532 		case RED_DIALOG_WARNING:
533 			d = XmCreateWarningDialog(w, "Warning", a, n);
534 
535 			break;
536 		case RED_DIALOG_WORKING:
537 			d = XmCreateWorkingDialog(w, "Working", a, n);
538 
539 			break;
540 		default:
541 			(void) XmStringFree(m);
542 
543 			p->the_end++;
544 
545 			return;
546 	}
547 
548 	(void) XtUnmanageChild(XmMessageBoxGetChild(d, XmDIALOG_OK_BUTTON));
549 	(void) XtUnmanageChild(XmMessageBoxGetChild(d, XmDIALOG_CANCEL_BUTTON));
550 	(void) XtUnmanageChild(XmMessageBoxGetChild(d, XmDIALOG_HELP_BUTTON));
551 
552 	for(i = 0; i < p->dialog.b_c; i++) {
553 		p->dialog.b_b[i].m = XmStringCreateLocalized(p->dialog.b_b[i].s);
554 
555 		(void) XtSetArg(a[0], XmNlabelString, p->dialog.b_b[i].m);
556 
557 		p->dialog.b_b[i].w = XmCreatePushButton(d, p->dialog.b_b[i].s, a, 1);
558 
559 		(void) XtAddCallback(p->dialog.b_b[i].w, XmNactivateCallback,
560 			redtools_req_dialog_cb, (XtPointer) &p->dialog.b_b[i]);
561 
562 		(void) XtManageChild(p->dialog.b_b[i].w);
563 	}
564 
565 	(void) XtAddCallback(d, XmNmapCallback,
566 		redtools_req_pu, NULL);
567 
568 	(void) XtManageChild(d);
569 	(void) XmStringFree(m);
570 
571 	for(i = 0; i < p->dialog.b_c; i++) (void) XmStringFree(p->dialog.b_b[i].m);
572 
573 	p->dialog.pressed = 0;
574 }
575 
redtools_req_dialog_cb(Widget w,XtPointer c,XtPointer d)576 static void redtools_req_dialog_cb(Widget w, XtPointer c, XtPointer d) {
577 	struct d_par_dialog_b *b;
578 
579 	XmAnyCallbackStruct *a;
580 
581 	a = (XmAnyCallbackStruct *) d;
582 	b = (struct d_par_dialog_b *) c;
583 
584 	switch(a->reason) {
585 		case XmCR_ACTIVATE:
586 			(void) XtUnmanageChild(XtParent(w));
587 
588 			break;
589 		default:
590 			(void) XtUnmanageChild(w);
591 
592 			break;
593 	}
594 
595 	*b->pressed = b->c;
596 	*b->the_end = 1;
597 }
598 
redtools_req_dialog_title_add(struct d_par * p,char * s)599 static void redtools_req_dialog_title_add(struct d_par *p, char *s) {
600 	p->dialog.b_t.s = s;
601 }
602 
redtools_req_dialog_button_add(struct d_par * p,char * s)603 static void redtools_req_dialog_button_add(struct d_par *p, char *s) {
604 	if(p->dialog.b_c >= RED_DIALOG_MAX_BUTTONS) {
605 		(void) fprintf(
606 			stderr,
607 			_("Failed to add button, maximum limit of %u is reached.%c"),
608 			(unsigned int) RED_DIALOG_MAX_BUTTONS, CONFIG_LINE_FEED
609 		);
610 
611 		return;
612 	}
613 
614 	p->dialog.b_b[p->dialog.b_c].s = s;
615 	p->dialog.b_b[p->dialog.b_c].c = p->dialog.b_c + 1;
616 
617 	p->dialog.b_b[p->dialog.b_c].pressed = &p->dialog.pressed;
618 	p->dialog.b_b[p->dialog.b_c].the_end = &p->the_end;
619 
620 	p->dialog.b_c++;
621 }
622 
redtools_req_file_op(Widget w,struct d_par * p)623 static void redtools_req_file_op(Widget w, struct d_par *p) {
624 	int n;
625 
626 	Arg a[6];
627 	Widget d;
628 	XmString m[3];
629 
630 	if(p->file.head != NULL) {
631 		m[0] = XmStringCreateLocalized(p->file.head);
632 	}
633 	else {
634 		m[0] = XmStringCreateLocalized(_("Selection"));
635 	}
636 
637 	n = 0;
638 
639 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
640 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
641 	(void) XtSetArg(a[n], XmNpathMode, XmPATH_MODE_RELATIVE); n++;
642 	(void) XtSetArg(a[n], XmNdialogTitle, m[0]); n++;
643 
644 	if(p->file.path != NULL) {
645 		m[1] = XmStringCreateLocalized(p->file.path);
646 
647 		(void) XtSetArg(a[n], XmNdirectory, m[1]); n++;
648 	}
649 	else m[1] = NULL;
650 
651 	if(p->file.mask != NULL) {
652 		m[2] = XmStringCreateLocalized(p->file.mask);
653 
654 		(void) XtSetArg(a[n], XmNpattern, m[2]); n++;
655 	}
656 	else m[2] = NULL;
657 
658 	d = XmCreateFileSelectionDialog(w, "File", a, n);
659 
660 	(void) XtUnmanageChild(XmFileSelectionBoxGetChild(d, XmDIALOG_HELP_BUTTON));
661 
662 	(void) XtAddCallback(d, XmNokCallback,
663 		redtools_req_file_cb, (XtPointer) &p->file);
664 	(void) XtAddCallback(d, XmNcancelCallback,
665 		redtools_req_file_cb, (XtPointer) &p->file);
666 	(void) XtAddCallback(d, XmNmapCallback,
667 		redtools_req_pu, NULL);
668 
669 	(void) XtManageChild(d);
670 
671 	(void) XmStringFree(m[0]);
672 
673 	if(m[1] != NULL) (void) XmStringFree(m[1]);
674 	if(m[2] != NULL) (void) XmStringFree(m[2]);
675 
676 	p->file.file = NULL;
677 	p->file.the_end = &p->the_end;
678 }
679 
redtools_req_file_cb(Widget w,XtPointer c,XtPointer d)680 static void redtools_req_file_cb(Widget w, XtPointer c, XtPointer d) {
681 	struct d_par_file *b;
682 
683 	XmFileSelectionBoxCallbackStruct *a;
684 
685 	a = (XmFileSelectionBoxCallbackStruct *) d;
686 	b = (struct d_par_file *) c;
687 
688 	switch(a->reason) {
689 		case XmCR_OK:
690 			b->file = (char *) XmStringUnparse(a->value, XmFONTLIST_DEFAULT_TAG,
691 				XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
692 
693 			(void) XtUnmanageChild(w);
694 
695 			break;
696 		default:
697 			(void) XtUnmanageChild(w);
698 
699 			break;
700 	}
701 
702 	*b->the_end = 1;
703 }
704 
redtools_req_file_title_add(struct d_par * p,char * e)705 static void redtools_req_file_title_add(struct d_par *p, char *e) {
706 	p->file.head = e;
707 }
708 
redtools_req_file_path_add(struct d_par * p,char * s)709 static void redtools_req_file_path_add(struct d_par *p, char *s) {
710 	p->file.path = s;
711 }
712 
redtools_req_file_mask_add(struct d_par * p,char * s)713 static void redtools_req_file_mask_add(struct d_par *p, char *s) {
714 	p->file.mask = s;
715 }
716 
redtools_req_prompt_op(Widget w,struct d_par * p)717 static void redtools_req_prompt_op(Widget w, struct d_par *p) {
718 	int n;
719 
720 	Arg a[5];
721 	Widget d;
722 	XmString m[3];
723 
724 	if(p->prompt.head != NULL) {
725 		m[0] = XmStringCreateLocalized(p->prompt.head);
726 	}
727 	else {
728 		m[0] = XmStringCreateLocalized(_("Selection"));
729 	}
730 
731 	if(p->prompt.title != NULL) {
732 		m[1] = XmStringCreateLocalized(p->prompt.title);
733 	}
734 	else {
735 		m[1] = XmStringCreateLocalized(_("Input"));
736 	}
737 
738 	n = 0;
739 
740 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
741 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
742 	(void) XtSetArg(a[n], XmNdialogTitle, m[0]); n++;
743 	(void) XtSetArg(a[n], XmNselectionLabelString, m[1]); n++;
744 
745 	if(p->prompt.value != NULL) {
746 		m[2] = XmStringCreateLocalized(p->prompt.value);
747 
748 		(void) XtSetArg(a[n], XmNtextString, m[2]); n++;
749 	}
750 	else m[2] = NULL;
751 
752 	d = XmCreatePromptDialog(w, "Prompt", a, n);
753 
754 	(void) XtUnmanageChild(XmSelectionBoxGetChild(d, XmDIALOG_HELP_BUTTON));
755 
756 	(void) XtAddCallback(d, XmNokCallback,
757 		redtools_req_prompt_cb, (XtPointer) &p->prompt);
758 	(void) XtAddCallback(d, XmNcancelCallback,
759 		redtools_req_prompt_cb, (XtPointer) &p->prompt);
760 	(void) XtAddCallback(d, XmNmapCallback,
761 		redtools_req_pu, NULL);
762 
763 	(void) XtManageChild(d);
764 
765 	(void) XmStringFree(m[0]);
766 	(void) XmStringFree(m[1]);
767 
768 	if(m[2] != NULL) (void) XmStringFree(m[2]);
769 
770 	p->prompt.prompt = NULL;
771 	p->prompt.the_end = &p->the_end;
772 }
773 
redtools_req_prompt_cb(Widget w,XtPointer c,XtPointer d)774 static void redtools_req_prompt_cb(Widget w, XtPointer c, XtPointer d) {
775 	struct d_par_prompt *b;
776 
777 	XmSelectionBoxCallbackStruct *a;
778 
779 	a = (XmSelectionBoxCallbackStruct *) d;
780 	b = (struct d_par_prompt *) c;
781 
782 	switch(a->reason) {
783 		case XmCR_OK:
784 			b->prompt = (char *) XmStringUnparse(a->value, XmFONTLIST_DEFAULT_TAG,
785 				XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
786 
787 			(void) XtUnmanageChild(w);
788 
789 			break;
790 		default:
791 			(void) XtUnmanageChild(w);
792 
793 			break;
794 	}
795 
796 	*b->the_end = 1;
797 }
798 
redtools_req_prompt_title_add(struct d_par * p,char * e,char * s)799 static void redtools_req_prompt_title_add(struct d_par *p, char *e, char *s) {
800 	p->prompt.head = e;
801 	p->prompt.title = s;
802 }
803 
redtools_req_prompt_value_add(struct d_par * p,char * s)804 static void redtools_req_prompt_value_add(struct d_par *p, char *s) {
805 	p->prompt.value = s;
806 }
807 
redtools_req_list_op(Widget w,struct d_par * p)808 static void redtools_req_list_op(Widget w, struct d_par *p) {
809 	unsigned int i;
810 	int n;
811 
812 	Arg a[8];
813 	Widget d[6];
814 	XmString m;
815 	XmStringTable o;
816 
817 	o = (XmStringTable) XtMalloc(sizeof(XmString *) * p->list.i_c);
818 
819 	for(i = 0; i < p->list.i_c; i++) o[i] = XmStringCreateLocalized(p->list.i_t[i]->s);
820 
821 	if(p->list.head != NULL) {
822 		m = XmStringCreateLocalized(p->list.head);
823 	}
824 	else {
825 		m = XmStringCreateLocalized(_("Selection"));
826 	}
827 
828 	n = 0;
829 
830 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
831 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
832 	(void) XtSetArg(a[n], XmNdialogTitle, m); n++;
833 
834 	d[0] = XmCreateFormDialog(w, "Listform", a, n);
835 
836 	(void) XmStringFree(m);
837 
838 	if(p->list.title != NULL) {
839 		m = XmStringCreateLocalized(p->list.title);
840 	}
841 	else {
842 		m = XmStringCreateLocalized(_("Items"));
843 	}
844 
845 	n = 0;
846 
847 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
848 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
849 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_FORM); n++;
850 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
851 
852 	d[1] = XmCreateLabel(d[0], "Listlabel", a, n);
853 
854 	(void) XtManageChild(d[1]);
855 	(void) XmStringFree(m);
856 
857 	n = 0;
858 
859 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
860 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
861 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
862 	(void) XtSetArg(a[n], XmNtopWidget, d[1]); n++;
863 	(void) XtSetArg(a[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++;
864 	(void) XtSetArg(a[n], XmNvisibleItemCount, 24); n++;
865 	(void) XtSetArg(a[n], XmNitems, o); n++;
866 	(void) XtSetArg(a[n], XmNitemCount, p->list.i_c); n++;
867 
868 	d[2] = XmCreateScrolledList(d[0], "List", a, n);
869 
870 	p->list.w = d[2];
871 
872 	(void) XtAddCallback(d[2], XmNdefaultActionCallback,
873 		redtools_req_list_cb, (XtPointer) &p->list);
874 	(void) XtAddCallback(d[2], XmNsingleSelectionCallback,
875 		redtools_req_list_cb, (XtPointer) &p->list);
876 	(void) XtAddCallback(d[2], XmNmultipleSelectionCallback,
877 		redtools_req_list_cb, (XtPointer) &p->list);
878 	(void) XtAddCallback(d[2], XmNextendedSelectionCallback,
879 		redtools_req_list_cb, (XtPointer) &p->list);
880 
881 	(void) XtManageChild(d[2]);
882 
883 	m = XmStringCreateLocalized(_("Regex Search"));
884 
885 	n = 0;
886 
887 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
888 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
889 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
890 	(void) XtSetArg(a[n], XmNtopWidget, d[2]); n++;
891 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
892 
893 	d[3] = XmCreateLabel(d[0], "Searchlabel", a, n);
894 
895 	(void) XtManageChild(d[3]);
896 	(void) XmStringFree(m);
897 
898 	n = 0;
899 
900 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
901 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
902 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
903 	(void) XtSetArg(a[n], XmNtopWidget, d[3]); n++;
904 	(void) XtSetArg(a[n], XmNcolumns, 48); n++;
905 
906 	d[4] = XmCreateTextField(d[0], "Search", a, n);
907 
908 	(void) XtAddCallback(d[4], XmNactivateCallback,
909 		redtools_req_list_search_cb, (XtPointer) d[2]);
910 
911 	(void) XtManageChild(d[4]);
912 
913 	m = XmStringCreateLocalized(_("Select"));
914 
915 	n = 0;
916 
917 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
918 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
919 	(void) XtSetArg(a[n], XmNbottomAttachment, XmATTACH_FORM); n++;
920 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
921 	(void) XtSetArg(a[n], XmNtopWidget, d[4]); n++;
922 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
923 
924 	d[5] = XmCreatePushButton(d[0], "Select", a, n);
925 
926 	(void) XtAddCallback(d[5], XmNactivateCallback,
927 		redtools_req_list_select_cb, (XtPointer) &p->list);
928 
929 	(void) XtManageChild(d[5]);
930 	(void) XmStringFree(m);
931 
932 	(void) XtAddCallback(d[0], XmNmapCallback,
933 		redtools_req_pu, NULL);
934 
935 	(void) XtManageChild(d[0]);
936 
937 	for(i = 0; i < p->list.i_c; i++) (void) XmStringFree(o[i]);
938 
939 	(void) XtFree((char *) o);
940 
941 	p->list.list = NULL;
942 	p->list.the_end = &p->the_end;
943 }
944 
redtools_req_list_cb(Widget w,XtPointer c,XtPointer d)945 static void redtools_req_list_cb(Widget w, XtPointer c, XtPointer d) {
946 	int i;
947 
948 	size_t t;
949 
950 	struct d_par_list *b;
951 
952 	XmListCallbackStruct *a;
953 
954 	a = (XmListCallbackStruct *) d;
955 	b = (struct d_par_list *) c;
956 
957 	switch(a->reason) {
958 		case XmCR_SINGLE_SELECT:
959 		case XmCR_MULTIPLE_SELECT:
960 		case XmCR_EXTENDED_SELECT:
961 			break;
962 		default:
963 			t = sizeof(unsigned int) * (a->selected_item_count + 1);
964 			if((b->list = malloc(t)) == NULL) {
965 				(void) fprintf(
966 					stderr,
967 					_("Failed to allocate %lu bytes of memory: %s.%c"),
968 					(unsigned long) t, strerror(errno), CONFIG_LINE_FEED
969 				);
970 
971 				return;
972 			}
973 
974 			for(i = 0; i < a->selected_item_count; i++) {
975 				b->list[i] = (unsigned int) a->selected_item_positions[i];
976 			}
977 
978 			b->list[a->selected_item_count] = 0;
979 
980 			(void) XtUnmanageChild(XtParent(XtParent(w)));
981 
982 			*b->the_end = 1;
983 
984 			break;
985 	}
986 }
987 
redtools_req_list_search_cb(Widget w,XtPointer c,__UNUSED__ XtPointer d)988 static void redtools_req_list_search_cb(Widget w, XtPointer c, __UNUSED__ XtPointer d) {
989 	int i, n, r;
990 
991 	char *s, *e;
992 
993 	Widget a;
994 	XmString *p, *u;
995 
996 	regex_t t;
997 
998 	char b[1024];
999 
1000 	a = (Widget) c;
1001 	s = XmTextFieldGetString(w);
1002 
1003 	if(s == NULL || s[0] == 0) {
1004 		(void) XtFree(s);
1005 
1006 		return;
1007 	}
1008 
1009 	if((r = regcomp(&t, (const char *) s, REG_EXTENDED | REG_NOSUB)) != 0) {
1010 		(void) regerror(r, &t, b, sizeof(b));
1011 
1012 		(void) fprintf(
1013 			stderr,
1014 			_("Failed to compile regular expression: %s.%c"),
1015 			b, CONFIG_LINE_FEED
1016 		);
1017 
1018 		(void) XtFree(s);
1019 
1020 		return;
1021 	}
1022 
1023 	i = 0;
1024 	n = 0;
1025 	u = NULL;
1026 
1027 	(void) XtFree(s);
1028 	(void) XtVaGetValues(a, XmNitemCount, &n, XmNitems, &p, NULL);
1029 
1030 	while(n--) {
1031 		if((e = (char *) XmStringUnparse(p[n], XmFONTLIST_DEFAULT_TAG,
1032 			XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL)) == NULL) break;
1033 
1034 		if((r = regexec(&t, (const char *) e, 0, NULL, 0)) == 0) {
1035 			u = (XmString *) XtRealloc((char *) u, sizeof(XmString *) * (i + 1));
1036 
1037 			u[i++] = XmStringCopy(p[n]);
1038 		}
1039 		else if(r != REG_NOMATCH) {
1040 			(void) regerror(r, &t, b, sizeof(b));
1041 
1042 			(void) fprintf(
1043 				stderr,
1044 				_("Failed to execute regular expression: %s.%c"),
1045 				b, CONFIG_LINE_FEED
1046 			);
1047 		}
1048 
1049 		(void) XtFree(e);
1050 	}
1051 
1052 	(void) regfree(&t);
1053 
1054 	(void) XtVaSetValues(a, XmNselectedItems, u, XmNselectedItemCount, i, NULL);
1055 
1056 	while(i--) (void) XmStringFree(u[i]);
1057 }
1058 
redtools_req_list_select_cb(Widget w,XtPointer c,__UNUSED__ XtPointer d)1059 static void redtools_req_list_select_cb(Widget w, XtPointer c, __UNUSED__ XtPointer d) {
1060 	int i, n;
1061 	int *p;
1062 
1063 	size_t t;
1064 
1065 	struct d_par_list *b;
1066 
1067 	b = (struct d_par_list *) c;
1068 
1069 	n = 0;
1070 	p = NULL;
1071 
1072 	(void) XtVaGetValues(b->w, XmNselectedPositionCount, &n, XmNselectedPositions, &p, NULL);
1073 
1074 	if(n != 0) {
1075 		t = sizeof(unsigned int) * (n + 1);
1076 
1077 		if((b->list = malloc(t)) == NULL) {
1078 			(void) fprintf(
1079 				stderr,
1080 				_("Failed to allocate %lu bytes of memory: %s.%c"),
1081 				(unsigned long) t, strerror(errno), CONFIG_LINE_FEED
1082 			);
1083 
1084 			(void) XtFree((char *) p);
1085 
1086 			return;
1087 		}
1088 
1089 		for(i = 0; i < n; i++) b->list[i] = (unsigned int) p[i];
1090 
1091 		b->list[n] = 0;
1092 
1093 		(void) XtUnmanageChild(XtParent(w));
1094 
1095 		*b->the_end = 1;
1096 	}
1097 
1098 	(void) XtFree((char *) p);
1099 }
1100 
redtools_req_list_title_add(struct d_par * p,char * e,char * s)1101 static void redtools_req_list_title_add(struct d_par *p, char *e, char *s) {
1102 	p->list.head = e;
1103 	p->list.title = s;
1104 }
1105 
redtools_req_list_item_add(struct d_par * p,char * s)1106 static void redtools_req_list_item_add(struct d_par *p, char *s) {
1107 	struct d_par_list_t **r;
1108 
1109 	if((r = realloc(p->list.i_t, sizeof(struct d_par_list_t *) * (p->list.i_c + 1))) == NULL) {
1110 		(void) fprintf(
1111 			stderr,
1112 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1113 			(unsigned long) (sizeof(struct d_par_list_t *) * (p->list.i_c + 1)), strerror(errno), CONFIG_LINE_FEED
1114 		);
1115 
1116 		return;
1117 	}
1118 
1119 	p->list.i_t = r;
1120 
1121 	if((p->list.i_t[p->list.i_c] = malloc(sizeof(struct d_par_list_t))) == NULL) {
1122 		(void) fprintf(
1123 			stderr,
1124 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1125 			(unsigned long) sizeof(struct d_par_list_t), strerror(errno), CONFIG_LINE_FEED
1126 		);
1127 
1128 		return;
1129 	}
1130 
1131 	p->list.i_t[p->list.i_c]->s = s;
1132 
1133 	p->list.i_c++;
1134 }
1135 
redtools_req_radio_op(Widget w,struct d_par * p)1136 static void redtools_req_radio_op(Widget w, struct d_par *p) {
1137 	unsigned int i;
1138 	int n;
1139 
1140 	Arg a[9];
1141 	Widget k;
1142 	Widget d[4];
1143 	XmString m;
1144 
1145 	if(p->radio.head != NULL) {
1146 		m = XmStringCreateLocalized(p->radio.head);
1147 	}
1148 	else {
1149 		m = XmStringCreateLocalized(_("Selection"));
1150 	}
1151 
1152 	n = 0;
1153 
1154 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
1155 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
1156 	(void) XtSetArg(a[n], XmNdialogTitle, m); n++;
1157 
1158 	d[0] = XmCreateFormDialog(w, "Radioform", a, n);
1159 
1160 	(void) XmStringFree(m);
1161 
1162 	if(p->radio.title != NULL) {
1163 		m = XmStringCreateLocalized(p->radio.title);
1164 	}
1165 	else {
1166 		m = XmStringCreateLocalized(_("Items"));
1167 	}
1168 
1169 	n = 0;
1170 
1171 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1172 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1173 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_FORM); n++;
1174 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
1175 
1176 	d[1] = XmCreateLabel(d[0], "Radiolabel", a, n);
1177 
1178 	(void) XtManageChild(d[1]);
1179 	(void) XmStringFree(m);
1180 
1181 	n = 0;
1182 
1183 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1184 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1185 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
1186 	(void) XtSetArg(a[n], XmNtopWidget, d[1]); n++;
1187 
1188 	d[2] = XmCreateRadioBox(d[0], "Radio", a, n);
1189 
1190 	k = d[2];
1191 
1192 	for(i = 0; i < p->radio.i_c; i++) {
1193 		m = XmStringCreateLocalized(p->radio.i_t[i]->s);
1194 
1195 		n = 0;
1196 
1197 		(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1198 		(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1199 		(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
1200 		(void) XtSetArg(a[n], XmNtopWidget, k); n++;
1201 		(void) XtSetArg(a[n], XmNlabelString, m); n++;
1202 		(void) XtSetArg(a[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
1203 		(void) XtSetArg(a[n], XmNindicatorType, XmONE_OF_MANY); n++;
1204 		(void) XtSetArg(a[n], XmNindicatorOn, XmINDICATOR_FILL); n++;
1205 
1206 		if(p->radio.preset != 0 && p->radio.preset - 1 == i) {
1207 			(void) XtSetArg(a[n], XmNset, True); n++;
1208 
1209 			p->radio.i_t[i]->pressed = 1;
1210 		}
1211 
1212 		p->radio.i_t[i]->d = XmCreateToggleButton(d[2], "Button", a, n);
1213 
1214 		(void) XtAddCallback(p->radio.i_t[i]->d, XmNvalueChangedCallback,
1215 			redtools_req_radio_cb, (XtPointer) p->radio.i_t[i]);
1216 
1217 		(void) XtManageChild(p->radio.i_t[i]->d);
1218 		(void) XmStringFree(m);
1219 
1220 		k = p->radio.i_t[i]->d;
1221 	}
1222 
1223 	(void) XtManageChild(d[2]);
1224 
1225 	m = XmStringCreateLocalized(_("Select"));
1226 
1227 	n = 0;
1228 
1229 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1230 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1231 	(void) XtSetArg(a[n], XmNbottomAttachment, XmATTACH_FORM); n++;
1232 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
1233 	(void) XtSetArg(a[n], XmNtopWidget, d[2]); n++;
1234 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
1235 
1236 	d[3] = XmCreatePushButton(d[0], "Select", a, n);
1237 
1238 	(void) XtAddCallback(d[3], XmNactivateCallback,
1239 		redtools_req_radio_select_cb, (XtPointer) &p->radio);
1240 
1241 	(void) XtManageChild(d[3]);
1242 	(void) XmStringFree(m);
1243 
1244 	(void) XtAddCallback(d[0], XmNmapCallback,
1245 		redtools_req_pu, NULL);
1246 
1247 	(void) XtManageChild(d[0]);
1248 
1249 	p->radio.button = 0;
1250 	p->radio.the_end = &p->the_end;
1251 }
1252 
redtools_req_radio_cb(__UNUSED__ Widget w,XtPointer c,XtPointer d)1253 static void redtools_req_radio_cb(__UNUSED__ Widget w, XtPointer c, XtPointer d) {
1254 	struct d_par_radio_t *b;
1255 
1256 	XmToggleButtonCallbackStruct *a;
1257 
1258 	a = (XmToggleButtonCallbackStruct *) d;
1259 	b = (struct d_par_radio_t *) c;
1260 
1261 	switch(a->set) {
1262 		case XmSET:
1263 			b->pressed = 1;
1264 
1265 			break;
1266 		case XmOFF:
1267 			b->pressed = 0;
1268 
1269 			break;
1270 		default:
1271 			break;
1272 	}
1273 }
1274 
redtools_req_radio_select_cb(Widget w,XtPointer c,__UNUSED__ XtPointer d)1275 static void redtools_req_radio_select_cb(Widget w, XtPointer c, __UNUSED__ XtPointer d) {
1276 	unsigned int i;
1277 
1278 	struct d_par_radio *b;
1279 
1280 	b = (struct d_par_radio *) c;
1281 
1282 	for(i = 0; i < b->i_c; i++) {
1283 		if(b->i_t[i]->pressed != 0) {
1284 			b->button = i + 1;
1285 
1286 			break;
1287 		}
1288 	}
1289 
1290 	(void) XtUnmanageChild(XtParent(w));
1291 
1292 	*b->the_end = 1;
1293 }
1294 
redtools_req_radio_title_add(struct d_par * p,char * e,char * s)1295 static void redtools_req_radio_title_add(struct d_par *p, char *e, char *s) {
1296 	p->radio.head = e;
1297 	p->radio.title = s;
1298 }
1299 
redtools_req_radio_item_add(struct d_par * p,char * s)1300 static void redtools_req_radio_item_add(struct d_par *p, char *s) {
1301 	struct d_par_radio_t **r;
1302 
1303 	if((r = realloc(p->radio.i_t, sizeof(struct d_par_radio_t *) * (p->radio.i_c + 1))) == NULL) {
1304 		(void) fprintf(
1305 			stderr,
1306 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1307 			(unsigned long) (sizeof(struct d_par_radio_t *) * (p->radio.i_c + 1)), strerror(errno), CONFIG_LINE_FEED
1308 		);
1309 
1310 		return;
1311 	}
1312 
1313 	p->radio.i_t = r;
1314 
1315 	if((p->radio.i_t[p->radio.i_c] = malloc(sizeof(struct d_par_radio_t))) == NULL) {
1316 		(void) fprintf(
1317 			stderr,
1318 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1319 			(unsigned long) sizeof(struct d_par_radio_t), strerror(errno), CONFIG_LINE_FEED
1320 		);
1321 
1322 		return;
1323 	}
1324 
1325 	p->radio.i_t[p->radio.i_c]->pressed = 0;
1326 	p->radio.i_t[p->radio.i_c]->s = s;
1327 
1328 	p->radio.i_c++;
1329 }
1330 
redtools_req_radio_preset_add(struct d_par * p,unsigned int n)1331 static void redtools_req_radio_preset_add(struct d_par *p, unsigned int n) {
1332 	p->radio.preset = n;
1333 }
1334 
redtools_req_button_op(Widget w,struct d_par * p)1335 static void redtools_req_button_op(Widget w, struct d_par *p) {
1336 	unsigned int i, o, v, x;
1337 	int n;
1338 
1339 	Arg a[9];
1340 	Widget k;
1341 	Widget d[3];
1342 	XmString m;
1343 
1344 	if(p->button.head != NULL) {
1345 		m = XmStringCreateLocalized(p->button.head);
1346 	}
1347 	else {
1348 		m = XmStringCreateLocalized(_("Selection"));
1349 	}
1350 
1351 	n = 0;
1352 
1353 	(void) XtSetArg(a[n], XmNautoUnmanage, False); n++;
1354 	(void) XtSetArg(a[n], XmNdefaultPosition, False); n++;
1355 	(void) XtSetArg(a[n], XmNdialogTitle, m); n++;
1356 
1357 	d[0] = XmCreateFormDialog(w, "Buttonform", a, n);
1358 
1359 	(void) XmStringFree(m);
1360 
1361 	if(p->button.title != NULL) {
1362 		m = XmStringCreateLocalized(p->button.title);
1363 	}
1364 	else {
1365 		m = XmStringCreateLocalized(_("Items"));
1366 	}
1367 
1368 	n = 0;
1369 
1370 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1371 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1372 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_FORM); n++;
1373 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
1374 
1375 	d[1] = XmCreateLabel(d[0], "Buttonlabel", a, n);
1376 
1377 	(void) XtManageChild(d[1]);
1378 	(void) XmStringFree(m);
1379 
1380 	k = d[1];
1381 
1382 	for(i = 0; i < p->button.i_c; i++) {
1383 		m = XmStringCreateLocalized(p->button.i_t[i]->s);
1384 
1385 		n = 0;
1386 
1387 		(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1388 		(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1389 		(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
1390 		(void) XtSetArg(a[n], XmNtopWidget, k); n++;
1391 		(void) XtSetArg(a[n], XmNlabelString, m); n++;
1392 		(void) XtSetArg(a[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
1393 		(void) XtSetArg(a[n], XmNindicatorType, XmN_OF_MANY); n++;
1394 		(void) XtSetArg(a[n], XmNindicatorOn, XmINDICATOR_CHECK); n++;
1395 
1396 		if(p->button.preset != NULL) {
1397 			o = i / (sizeof(unsigned int) * 8);
1398 			v = i % (sizeof(unsigned int) * 8);
1399 			x = 1 << v;
1400 
1401 			if((p->button.preset[o] & x) != 0) {
1402 				(void) XtSetArg(a[n], XmNset, True); n++;
1403 
1404 				p->button.i_t[i]->pressed = 1;
1405 			}
1406 		}
1407 
1408 		p->button.i_t[i]->d = XmCreateToggleButton(d[0], "Button", a, n);
1409 
1410 		(void) XtAddCallback(p->button.i_t[i]->d, XmNvalueChangedCallback,
1411 			redtools_req_button_cb, (XtPointer) p->button.i_t[i]);
1412 
1413 		(void) XtManageChild(p->button.i_t[i]->d);
1414 		(void) XmStringFree(m);
1415 
1416 		k = p->button.i_t[i]->d;
1417 	}
1418 
1419 	m = XmStringCreateLocalized(_("Select"));
1420 
1421 	n = 0;
1422 
1423 	(void) XtSetArg(a[n], XmNleftAttachment, XmATTACH_FORM); n++;
1424 	(void) XtSetArg(a[n], XmNrightAttachment, XmATTACH_FORM); n++;
1425 	(void) XtSetArg(a[n], XmNbottomAttachment, XmATTACH_FORM); n++;
1426 	(void) XtSetArg(a[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
1427 	(void) XtSetArg(a[n], XmNtopWidget, k); n++;
1428 	(void) XtSetArg(a[n], XmNlabelString, m); n++;
1429 
1430 	d[2] = XmCreatePushButton(d[0], "Select", a, n);
1431 
1432 	(void) XtAddCallback(d[2], XmNactivateCallback,
1433 		redtools_req_button_select_cb, (XtPointer) &p->button);
1434 
1435 	(void) XtManageChild(d[2]);
1436 	(void) XmStringFree(m);
1437 
1438 	(void) XtAddCallback(d[0], XmNmapCallback,
1439 		redtools_req_pu, NULL);
1440 
1441 	(void) XtManageChild(d[0]);
1442 
1443 	p->button.button = NULL;
1444 	p->button.the_end = &p->the_end;
1445 }
1446 
redtools_req_button_cb(__UNUSED__ Widget w,XtPointer c,XtPointer d)1447 static void redtools_req_button_cb(__UNUSED__ Widget w, XtPointer c, XtPointer d) {
1448 	struct d_par_button_t *b;
1449 
1450 	XmToggleButtonCallbackStruct *a;
1451 
1452 	a = (XmToggleButtonCallbackStruct *) d;
1453 	b = (struct d_par_button_t *) c;
1454 
1455 	switch(a->set) {
1456 		case XmSET:
1457 			b->pressed = 1;
1458 
1459 			break;
1460 		case XmOFF:
1461 			b->pressed = 0;
1462 
1463 			break;
1464 		default:
1465 			break;
1466 	}
1467 }
1468 
redtools_req_button_select_cb(Widget w,XtPointer c,__UNUSED__ XtPointer d)1469 static void redtools_req_button_select_cb(Widget w, XtPointer c, __UNUSED__ XtPointer d) {
1470 	unsigned int i;
1471 
1472 	size_t t;
1473 
1474 	struct d_par_button *b;
1475 
1476 	b = (struct d_par_button *) c;
1477 	t = sizeof(unsigned int) * (b->i_c);
1478 
1479 	if((b->button = malloc(t)) == NULL) {
1480 		(void) fprintf(
1481 			stderr,
1482 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1483 			(unsigned long) t, strerror(errno), CONFIG_LINE_FEED
1484 		);
1485 
1486 		return;
1487 	}
1488 
1489 	for(i = 0; i < b->i_c; i++) b->button[i] = b->i_t[i]->pressed;
1490 
1491 	(void) XtUnmanageChild(XtParent(w));
1492 
1493 	*b->the_end = 1;
1494 }
1495 
redtools_req_button_title_add(struct d_par * p,char * e,char * s)1496 static void redtools_req_button_title_add(struct d_par *p, char *e, char *s) {
1497 	p->button.head = e;
1498 	p->button.title = s;
1499 }
1500 
redtools_req_button_item_add(struct d_par * p,char * s)1501 static void redtools_req_button_item_add(struct d_par *p, char *s) {
1502 	struct d_par_button_t **r;
1503 
1504 	if((r = realloc(p->button.i_t, sizeof(struct d_par_button_t *) * (p->button.i_c + 1))) == NULL) {
1505 		(void) fprintf(
1506 			stderr,
1507 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1508 			(unsigned long) (sizeof(struct d_par_button_t *) * (p->button.i_c + 1)), strerror(errno), CONFIG_LINE_FEED
1509 		);
1510 
1511 		return;
1512 	}
1513 
1514 	p->button.i_t = r;
1515 
1516 	if((p->button.i_t[p->button.i_c] = malloc(sizeof(struct d_par_button_t))) == NULL) {
1517 		(void) fprintf(
1518 			stderr,
1519 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1520 			(unsigned long) sizeof(struct d_par_button_t), strerror(errno), CONFIG_LINE_FEED
1521 		);
1522 
1523 		return;
1524 	}
1525 
1526 	p->button.i_t[p->button.i_c]->pressed = 0;
1527 	p->button.i_t[p->button.i_c]->s = s;
1528 
1529 	p->button.i_c++;
1530 }
1531 
redtools_req_button_preset_add(struct d_par * p,unsigned int * n)1532 static void redtools_req_button_preset_add(struct d_par *p, unsigned int *n) {
1533 	p->button.preset = n;
1534 }
1535 
redtools_req_pu(Widget w,__UNUSED__ XtPointer c,__UNUSED__ XtPointer d)1536 static void redtools_req_pu(Widget w, __UNUSED__ XtPointer c, __UNUSED__ XtPointer d) {
1537 	Dimension e, f;
1538 	Position x, y;
1539 
1540 	(void) XtVaGetValues(w, XmNwidth, &e, XmNheight, &f, NULL);
1541 
1542 	x = ((Dimension) WidthOfScreen(XtScreen(w)) - e) / 2;
1543 	y = ((Dimension) HeightOfScreen(XtScreen(w)) - f) / 2;
1544 
1545 	if(x < 0) x = 0;
1546 	if(y < 0) y = 0;
1547 
1548 	(void) XtVaSetValues(w, XmNx, x, XmNy, y, NULL);
1549 }
1550 
redtools_req_open(struct w_app * w,struct d_par * p)1551 static void redtools_req_open(struct w_app *w, struct d_par *p) {
1552 	Atom t;
1553 	XEvent e;
1554 
1555 	(void) XLockDisplay(w->d);
1556 
1557 	t = XInternAtom(w->d, "WM_DELETE_WINDOW", False);
1558 
1559 	(void) XUnlockDisplay(w->d);
1560 	(void) XtAppLock(w->a);
1561 
1562 	(void) redtools_req_open_op(w, p);
1563 
1564 	(void) XtAppUnlock(w->a);
1565 
1566 	while(p->the_end == 0) {
1567 		(void) XtAppLock(w->a);
1568 		(void) XtAppNextEvent(w->a, &e);
1569 
1570 		switch(e.type) {
1571 			case ClientMessage:
1572 				if(t == (Atom) e.xclient.data.l[0]) p->the_end++;
1573 
1574 				break;
1575 			case DestroyNotify:
1576 				p->the_end++;
1577 
1578 				break;
1579 			default:
1580 				break;
1581 		}
1582 
1583 		(void) XtDispatchEvent(&e);
1584 		(void) XtAppUnlock(w->a);
1585 	}
1586 }
1587 
redtools_req_open_op(struct w_app * w,struct d_par * p)1588 static void redtools_req_open_op(struct w_app *w, struct d_par *p) {
1589 	p->the_end = 0;
1590 
1591 	switch(p->class) {
1592 		case RED_CLASS_DIALOG:
1593 			(void) redtools_req_dialog_op(w->t, p);
1594 
1595 			break;
1596 		case RED_CLASS_FILE:
1597 			(void) redtools_req_file_op(w->t, p);
1598 
1599 			break;
1600 		case RED_CLASS_PROMPT:
1601 			(void) redtools_req_prompt_op(w->t, p);
1602 
1603 			break;
1604 		case RED_CLASS_LIST:
1605 			(void) redtools_req_list_op(w->t, p);
1606 
1607 			break;
1608 		case RED_CLASS_RADIO:
1609 			(void) redtools_req_radio_op(w->t, p);
1610 
1611 			break;
1612 		case RED_CLASS_BUTTON:
1613 			(void) redtools_req_button_op(w->t, p);
1614 
1615 			break;
1616 		default:
1617 			p->the_end++;
1618 
1619 			break;
1620 	}
1621 }
1622 
redtools_req_initialize(struct w_app * w)1623 static void redtools_req_initialize(struct w_app *w) {
1624 	int argc;
1625 	char **argv;
1626 
1627 	(void) XtToolkitInitialize();
1628 	(void) XtToolkitThreadInitialize();
1629 	(void) XtSetLanguageProc(NULL, NULL, NULL);
1630 
1631 	argc = 0;
1632 	argv = NULL;
1633 
1634 	w->t = XtOpenApplication(&w->a, "Redtools", NULL, 0,
1635 		&argc, argv,
1636 		(String *) f_res, sessionShellWidgetClass, NULL, 0);
1637 
1638 	(void) XtAppLock(w->a);
1639 
1640 	w->d = XtDisplay(w->t);
1641 	w->s = XtScreen(w->t);
1642 
1643 	(void) XtAppUnlock(w->a);
1644 	(void) XLockDisplay(w->d);
1645 
1646 	w->e = XDefaultScreen(w->d);
1647 	w->r = XDefaultRootWindow(w->d);
1648 
1649 	(void) XUnlockDisplay(w->d);
1650 }
1651 
redtools_req_finalize(struct w_app * w)1652 static void redtools_req_finalize(struct w_app *w) {
1653 	(void) XtCloseDisplay(w->d);
1654 	(void) XtDestroyApplicationContext(w->a);
1655 }
1656