1 /*
2  * Copyright (C) 1990 Regents of the University of California.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee,
6  * provided that the above copyright notice appear in all copies and that
7  * both that copyright notice and this permission notice appear in
8  * supporting documentation, and that the name of the University of
9  * California not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior
11  * permission.  the University of California makes no representations
12  * about the suitability of this software for any purpose.  It is provided
13  * "as is" without express or implied warranty.
14  */
15 
16 # include <X11/Intrinsic.h>
17 # include <X11/StringDefs.h>
18 # include <X11/Shell.h>
19 # include <X11/Xaw/Form.h>
20 # include <X11/Xaw/Label.h>
21 # include <X11/Xaw/List.h>
22 # include <X11/Xaw/Command.h>
23 # include <X11/Xaw/Toggle.h>
24 # include <X11/Xaw/Viewport.h>
25 # include <X11/Xaw/Dialog.h>
26 
27 
28 # include <stdio.h>
29 # include <string.h>
30 # include <stdlib.h>
31 
32 # include "debug.h"
33 # include "cdrom_globs.h"
34 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
35 # include "cdrom_freebsd.h"
36 #endif
37 #ifdef sun
38 # include "cdrom_sun.h"
39 #endif
40 #ifdef sgi
41 # include "cdrom_sgi.h"
42 #endif
43 
44 
45 /* externally manipulated vars: */
46 char	program_str[100];
47 char	*disc_title = NULL;
48 
49 static	Widget	program_form;
50 static	Widget	program_display_form;
51 static	Widget	program_anchor;
52 static	Widget	trackbuttons[9];
53 static	Widget	plus10_button;
54 static	Widget	new_track_button;
55 static	Boolean	adding_to_new_track = False;
56 static	struct	prognode *current_node = NULL;
57 
58 static	void    cb_move_program_ptr();
59 static	void    cb_clear_program();
60 static	void    cb_cancel_program();
61 static	void    cb_save_program();
62 static	void    cb_trackbuttons();
63 static	void    cb_add_10();
64 static	void    cb_new_track();
65 static	void    cb_program_all();
66 
67 void
program_form_setup(parent_widget)68 program_form_setup (parent_widget)
69 	Widget	parent_widget;
70 {
71         Arg	args[10];
72 	char	namestr[2];
73 	int	i;
74 
75 	Widget	program_display_viewport;
76 	Widget	track_select_form;
77 	Widget	clear_button;
78 	Widget	cancel_button;
79 	Widget	save_button;
80 	Widget	all_button;
81 
82 	/*
83 	 * create program form as a non-managed widget, because this
84 	 * form "pops up" when requested, as part of the main form, and
85 	 * therefore moves along with the main form. (Pop-ups don't do this
86 	 * easily.)
87 	 */
88         program_form = XtCreateWidget("programForm",
89 				formWidgetClass,
90                                 parent_widget,
91                                 (ArgList) NULL, 0);
92 
93         program_display_viewport = XtCreateManagedWidget(
94 				"programDisplayViewport",
95                                 viewportWidgetClass,
96 				program_form,
97                                 (ArgList) NULL, 0);
98 
99         program_display_form = XtCreateManagedWidget("programDisplayForm",
100                                 formWidgetClass,
101                                 program_display_viewport,
102                                 (ArgList) NULL, 0);
103 
104 
105 	XtSetArg(args[0], XtNlabel, " ");
106 	XtSetArg(args[1], XtNstate, TRUE);
107 	program_anchor = XtCreateManagedWidget("programSelection",
108 				toggleWidgetClass,
109 				program_display_form,
110 				(ArgList) args, 2);
111 	XtAddCallback (program_anchor, XtNcallback, cb_move_program_ptr, NULL);
112 
113 
114 	XtSetArg(args[0], XtNfromVert, program_display_viewport);
115 	clear_button = XtCreateManagedWidget("Clear",
116 				commandWidgetClass,
117 				program_form,
118 				(ArgList) args, 1);
119 	XtAddCallback (clear_button, XtNcallback, cb_clear_program, NULL);
120 
121 	XtSetArg(args[0], XtNfromVert, program_display_viewport);
122 	XtSetArg(args[1], XtNfromHoriz, clear_button);
123 	cancel_button = XtCreateManagedWidget("Cancel",
124 				commandWidgetClass,
125 				program_form,
126 				(ArgList) args, 2);
127 	XtAddCallback (cancel_button, XtNcallback, cb_cancel_program, NULL);
128 
129 
130 	XtSetArg(args[0], XtNfromVert, program_display_viewport);
131 	XtSetArg(args[1], XtNfromHoriz, cancel_button);
132 	save_button = XtCreateManagedWidget("Save",
133 				commandWidgetClass,
134 				program_form,
135 				(ArgList) args, 2);
136 	XtAddCallback (save_button, XtNcallback, cb_save_program, NULL);
137 
138 
139 	XtSetArg(args[0], XtNfromVert, clear_button);
140         track_select_form = XtCreateManagedWidget("selectForm",
141 				formWidgetClass,
142 				program_form,
143 				(ArgList) args, 1);
144 
145 
146 	for (i = 1; i <= 9; i++)
147 	{
148 	    sprintf(namestr, "%d",i);
149 	    trackbuttons[i-1] = XtCreateManagedWidget(namestr,
150 					commandWidgetClass,
151 					track_select_form,
152 					(ArgList) NULL, 0);
153 
154 	}
155 
156 	XtAddCallback (trackbuttons[0], XtNcallback, cb_trackbuttons, NULL);
157 
158 	for (i = 1; i < 9; i++)
159 	{
160 	    XtSetArg(args[0], XtNfromHoriz, trackbuttons[i-1]);
161 	    XtSetValues(trackbuttons[i], args, 1);
162 	    XtAddCallback (trackbuttons[i], XtNcallback, cb_trackbuttons, NULL);
163 	}
164 
165 	XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
166 	plus10_button = XtCreateManagedWidget("+10",
167 				commandWidgetClass,
168 				track_select_form,
169 				(ArgList) args, 1);
170 	XtAddCallback (plus10_button, XtNcallback, cb_add_10, NULL);
171 
172 	XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
173 	XtSetArg(args[1], XtNfromHoriz, plus10_button);
174 	new_track_button = XtCreateManagedWidget("  ",
175 				commandWidgetClass,
176 				track_select_form,
177 				(ArgList) args, 2);
178 	XtAddCallback (new_track_button, XtNcallback, cb_new_track, NULL);
179 
180 	XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
181 	XtSetArg(args[1], XtNfromHoriz, trackbuttons[6]);
182 	all_button = XtCreateManagedWidget("All",
183 				commandWidgetClass,
184 				track_select_form,
185 				(ArgList) args, 2);
186 	XtAddCallback (all_button, XtNcallback, cb_program_all, NULL);
187 
188 }
189 
190 void
popup_program_form(widget,topLevel,call_data)191 popup_program_form (widget, topLevel, call_data)
192 Widget		widget;
193 Widget		topLevel;
194 XtPointer	call_data;
195 {
196         Arg             args[2];
197 	int		i;
198 	char		*progstr;
199 	char		*token;
200 	int		track;
201 
202 	extern FILE     *disc_info;
203 
204 
205 	cdi.selection = NULL;
206 
207 	/* load saved program (if any) */
208 	if (disc_info != NULL)
209 	{
210 	    /* copy "open" program str for tokenization */
211 	    progstr = strdup(program_str);
212 	    token = strtok(progstr, "-"); 	/* find 1st programmed track */
213 	    if (token != NULL)
214 	    {
215 	        debug_printf(1, "using stored program\n");
216 	        while (token != NULL)
217 	        {
218 	            sscanf(token, "%d",&track); /* convert to # */
219 	            program_add_track((unsigned char)track);
220 	            token = strtok(NULL,"-"); /* get next track str */
221 	        }
222 	    }
223 	}
224 
225 	/* clear sensitivity for all */
226 	for (i=0; i < 9; i++)
227 	{
228 	    XtSetArg(args[0], XtNsensitive, FALSE);
229 	    XtSetValues(trackbuttons[i], args, 1);
230 	}
231 
232 	XtSetArg(args[0], XtNsensitive, FALSE);
233 	XtSetValues(plus10_button, args, 1);
234 	XtSetValues(new_track_button, args, 1);
235 
236 	for (i = 0; (i < 9) && (i < cdi.maxtrack); i++)
237 	{
238 	    /* set sensitivity for active buttons */
239 	    XtSetArg(args[0], XtNsensitive, TRUE);
240 	    XtSetValues(trackbuttons[i], args, 1);
241 	}
242 	if (cdi.maxtrack > 9)
243 	{
244 	    XtSetArg(args[0], XtNsensitive, TRUE);
245 	    XtSetValues(plus10_button, args, 1);
246 	}
247 
248 
249 	XtManageChild(program_form);
250 }
251 
252 
253 
254 void
make_program_button(node,next_to,label)255 make_program_button(node, next_to, label)
256 struct	prognode *node;
257 Widget	next_to;
258 char	label[];
259 {
260 	Arg	args[10];
261 	char	name[2];
262 	int	i = 0;
263 
264 	XtSetArg(args[i], XtNfromHoriz, next_to); i++;
265 	XtSetArg(args[i], XtNlabel, label); i++;
266 	XtSetArg(args[i], XtNradioGroup, program_anchor); i++;
267 	XtSetArg(args[i], XtNstate, TRUE); i++; /* activates *this* button */
268 
269 	node->button = XtCreateManagedWidget("programSelection",
270 				toggleWidgetClass,
271 				program_display_form,
272 				(ArgList) args, i);
273 	XtAddCallback(node->button, XtNcallback, cb_move_program_ptr,
274 		      (XtPointer) node);
275 
276 	if (node->next != NULL) /* then reposition widget following */
277 	{
278 	    XtSetArg(args[0], XtNfromHoriz, node->button);
279 	    XtSetValues(node->next->button, args, 1);
280 	}
281 }
282 
283 void
program_add_track(track)284 program_add_track (track)
285 unsigned char	track;
286 {
287 	struct prognode	*insert_point, *new, *next;
288 	Arg	args[10];
289 	char	*p;
290 	char	label[3];
291 	int	i;
292 
293 	XawFormDoLayout (program_display_form, FALSE);
294 
295 	if (cdi.program == NULL)
296 	{
297 	    new = (struct prognode *) malloc(sizeof(struct prognode));
298 	    new->track = track;
299 	    new->next = NULL;
300 	    new->prev = NULL;
301 	    current_node = cdi.program = new;
302 	    cdi.lastprog = 1;
303 
304 	    sprintf(label, "%d", track);
305 	    make_program_button(new, program_anchor, label);
306 	}
307 
308 	else if (current_node == NULL) /* pre-insert */
309 	{
310 	    new = (struct prognode *) malloc(sizeof(struct prognode));
311             new->track = track;
312             new->next = cdi.program;
313             new->prev = NULL;
314 	    current_node = cdi.program->prev = new;
315 	    cdi.program = cdi.program->prev;
316 	    cdi.lastprog++;
317 
318 	    sprintf(label, "%d", track);
319 	    make_program_button(new, program_anchor, label);
320 
321 	    sprintf(label, "-%d", new->next->track);
322 	    XtSetArg(args[0], XtNlabel, label);
323 	    XtSetValues(new->next->button, args, 1);
324 	}
325 	else
326 	{
327 	    insert_point = cdi.program;
328 
329 	    while ((insert_point->next != NULL) &&
330 		   (insert_point != current_node))
331 		 insert_point = insert_point->next;
332 
333 	    new = (struct prognode *) malloc(sizeof(struct prognode));
334 	    new->track = track;
335 	    new->next = insert_point->next;
336 	    new->prev = insert_point;
337 	    if (new->next != NULL)
338 	        new->next->prev = new; /* complete link back */
339 
340 	    cdi.lastprog++;
341 	    current_node = insert_point->next = new;
342 
343 	    sprintf(label, "-%d", track);
344 	    make_program_button(new, insert_point->button, label);
345 	}
346 
347 	next = cdi.program;
348 	sprintf(program_str, "%d", next->track);
349 	for (i = 1; i < cdi.lastprog; i++)
350 	{
351 	    next = next->next;
352 	    sprintf(program_str, "%s-%d", program_str, next->track);
353 	}
354 
355 
356 	XawFormDoLayout (program_display_form, TRUE);
357 
358 
359 	if (cdi.state & CDROM_STATE_PAUSE)
360 	{
361 	    cdi.selection = new;
362 	    cdi.curtrack = new->track;
363 	    track_button_update();
364 	    timer_button_update();
365 	}
366 }
367 
368 void
program_delete_track(node)369 program_delete_track (node)
370 struct prognode	*node;
371 {
372 	int i;
373 	Arg	args[2];
374 	char	*p;
375 	char	label[3];
376 
377 	if (cdi.program == NULL)
378 		return;
379 
380 	if (node->prev != NULL)
381 	{
382 	    node->prev->next = node->next;
383 	    current_node = node->prev;
384 	    XtSetArg(args[0], XtNstate, True);
385 	    XtSetValues(current_node->button, args, 1);
386 
387 	    XtSetArg(args[0], XtNfromHoriz, node->prev->button);
388 	}
389 	else
390 	{
391 	    cdi.program = node->next;
392 	    current_node = cdi.program;
393 	    if (current_node != NULL)
394 	    {
395 	    	sprintf(label, "%d", current_node->track);
396 	    	XtSetArg(args[0], XtNlabel, label);
397 	    	XtSetArg(args[1], XtNstate, True);
398 	    	XtSetValues(current_node->button, args, 2);
399 
400 	    	XtSetArg(args[0], XtNfromHoriz, program_anchor);
401 
402 	    }
403 	    else
404 	    {
405 	    	XtSetArg(args[0], XtNstate, True);
406 	    	XtSetValues(program_anchor, args, 1);
407 	    }
408 	}
409 
410 	if (node->next != NULL)
411 	{
412 	    node->next->prev = node->prev;
413 	    XtSetValues(node->next->button, args, 1);
414 	}
415 
416 
417 	XtDestroyWidget(node->button);
418 	free(node);
419 
420 	cdi.lastprog--;
421 
422 	if (cdi.program == NULL)
423 	{
424 	    program_str[0] = '\0';
425 	    cdi.selection = NULL;
426 	}
427 	else
428 	{
429 	    cdi.selection = current_node;
430 
431 	    if (cdi.state & CDROM_STATE_PAUSE)
432 	    {
433 		cdi.curtrack = current_node->track;
434 	    	track_button_update();
435 	    	timer_button_update();
436 	    }
437 
438 	    node = cdi.program;
439 	    sprintf(program_str, "%d", node->track);
440 	    for (i = 1; i < cdi.lastprog; i++)
441 	    {
442 		node = node->next;
443 		sprintf(program_str, "%s-%d", program_str, node->track);
444 	    }
445 	}
446 
447 }
448 
449 
450 int
program_time_remaining()451 program_time_remaining()
452 {
453 	struct prognode *node;
454 	int		time_remaining = 0;
455 
456 	if ((cdi.program == NULL) || (cdi.selection == NULL))
457 	    return (0);
458 
459 	node = cdi.selection;
460 	while (node != NULL)
461 	{
462 	    time_remaining += cdi.times[node->track - 1];
463 	    node = node->next;
464 	}
465 	time_remaining -= cdi.duration;
466 	return (time_remaining);
467 }
468 
469 
470 unsigned char
program_goto_next_track()471 program_goto_next_track()
472 {
473 	Arg	arg;
474 	Boolean	already_on;
475 
476 	if (cdi.program == NULL)
477 	    return (0);
478 	else if (cdi.selection == NULL)
479 	    cdi.selection = cdi.program;
480 	else if (cdi.selection->next == NULL)
481 	{
482 	    cdi.selection = NULL;
483 	    return (0);
484 	}
485 	else
486 	    cdi.selection = cdi.selection->next;
487 
488 
489 	XtSetArg(arg, XtNstate, &already_on);
490 	XtGetValues(cdi.selection->button, &arg, 1);
491 	if (already_on == FALSE)
492 	{
493 	    XtSetArg(arg, XtNstate, TRUE);
494 	    XtSetValues(cdi.selection->button, &arg, 1);
495 	}
496 
497 	pgm_button_set();
498 	return(cdi.selection->track);
499 }
500 
501 unsigned char
program_resume()502 program_resume()
503 {
504 	unsigned char	track;
505 
506 	if (cdi.program != NULL)
507 	{
508 	    if (cdi.selection == NULL)
509 		track = program_goto_next_track();
510 	    else
511 		track = cdi.selection->track;
512 	}
513 	else
514 	    track = cdi.curtrack;
515 	pgm_button_set();
516 
517 	return(track);
518 }
519 
520 
521 unsigned char
program_goto_prev_track()522 program_goto_prev_track()
523 {
524 	Arg	arg;
525 	Boolean	already_on;
526 
527 	if ((cdi.program == NULL) || (cdi.selection->prev == NULL))
528 	    return (0);
529 
530 	cdi.selection = cdi.selection->prev;
531 
532 	XtSetArg(arg, XtNstate, &already_on);
533 	XtGetValues(cdi.selection->button, &arg, 1);
534 	if (already_on == FALSE)
535 	{
536 	    XtSetArg(arg, XtNstate, TRUE);
537 	    XtSetValues(cdi.selection->button, &arg, 1);
538 	}
539 
540 	pgm_button_set();
541 	return (cdi.selection->track);
542 }
543 
544 unsigned char
program_next_track()545 program_next_track()
546 {
547 	if (cdi.program == NULL)
548 	    return (0);
549 
550 	else if (cdi.selection == NULL)
551 	    return (cdi.program->track);
552 
553 	else if (cdi.selection->next == NULL)
554 	    return (0);
555 	else
556 	    return (cdi.selection->next->track);
557 
558 }
559 
560 unsigned char
program_prev_track()561 program_prev_track()
562 {
563 	if ((cdi.program == NULL) || (cdi.selection == NULL) ||
564 	    (cdi.selection->prev == NULL))
565 	    return (0);
566 
567 	else
568 	    return (cdi.selection->prev->track);
569 
570 }
571 
572 void
clear_program()573 clear_program()
574 {
575 	Arg	arg;
576 
577 	/* clear new_track button and deactivate */
578 	XtSetArg(arg, XtNlabel, "  ");
579 	XtSetValues(new_track_button, &arg, 1);
580 	XtSetArg(arg, XtNsensitive, False);
581 	XtSetValues(new_track_button, &arg, 1);
582 	adding_to_new_track = False;
583 
584 	if (cdi.program == NULL)
585 	    return;
586 
587 	cdi.selection = cdi.program;
588 	while (cdi.selection->next != NULL)
589 	{
590 	    cdi.program = cdi.program-> next;
591 	    XtDestroyWidget(cdi.selection->button);
592 	    free(cdi.selection);
593 	    cdi.selection = cdi.program;
594 	}
595 	XtDestroyWidget(cdi.selection->button);
596 	free(cdi.selection);
597 	cdi.selection = cdi.program = NULL;
598 	cdi.lastprog = 0;
599 	XtSetArg(arg, XtNstate, True);
600 	XtSetValues(program_anchor, &arg, 1);
601 
602 	program_str[0]= '\0'; /* clear "store" string */
603 
604 }
605 
606 void
program_cancel()607 program_cancel()
608 {
609 	debug_printf(1, "program mode cancelled\n");
610 	clear_program();
611 
612 	XtUnmanageChild(program_form);
613 	pgm_button_reset();
614 	timer_button_reset();
615 	timer_button_update();
616 	cdi.state &= ~CDROM_STATE_PROGRAM;
617 }
618 
619 void
cb_move_program_ptr(widget,node,call_data)620 cb_move_program_ptr(widget, node, call_data)
621 Widget		widget;
622 struct prognode *node;
623 XtPointer	call_data;
624 {
625 	/*
626 	 * I cannot get XawToggleGetCurrent to work at all, so this
627 	 * is a bastardized way of doing this:
628 	 */
629 
630 	Arg	arg;
631 	Boolean	state;
632 
633 	XtSetArg(arg, XtNstate, &state);
634 	XtGetValues(widget, &arg, 1);
635 
636 	if (state == True)
637 	{
638 	    if ((current_node == node) && (current_node != NULL))
639 	    {
640 		debug_printf(1, "deleting selection from program\n");
641 		program_delete_track(node);
642 	    }
643 	    else
644 	    {
645 	        current_node = node;
646 
647 		if ((current_node != NULL) &&
648 		    ((cdi.state & CDROM_STATE_PAUSE) ||
649 		     ((cdi.state & CDROM_STATE_PLAY) == 0)))
650 		{
651 		    cdi.selection = node;
652 		    cdi.curtrack = node->track;
653 	    	    track_button_update();
654 	    	    timer_button_update();
655 		}
656 	    }
657 	}
658 
659 }
660 
661 
662 static void
cb_program_all(widget,client_data,call_data)663 cb_program_all(widget, client_data, call_data)
664 Widget		widget;
665 XtPointer	client_data;
666 XtPointer	call_data;
667 {
668 	Arg	arg;
669 	int i;
670 
671 	clear_program();
672 
673 	debug_printf(1, "program replaced by in-sequence track list\n");
674 	for (i = 1; i <= cdi.maxtrack; i++)
675 	    program_add_track ((unsigned char) i);
676 }
677 
678 static void
cb_clear_program(widget,client_data,call_data)679 cb_clear_program (widget, client_data, call_data)
680 Widget		widget;
681 XtPointer	client_data;
682 XtPointer	call_data;
683 {
684 	clear_program(); /* get rid of program */
685 	debug_printf(1, "program cleared\n");
686 }
687 
688 static void
cb_cancel_program(widget,client_data,call_data)689 cb_cancel_program (widget, client_data, call_data)
690 Widget		widget;
691 XtPointer	client_data;
692 XtPointer	call_data;
693 {
694 	program_cancel(); /* get rid of program and form */
695 }
696 
697 void
cb_save_program(widget,client_data,call_data)698 cb_save_program (widget, client_data, call_data)
699 Widget		widget;
700 XtPointer	client_data;
701 XtPointer	call_data;
702 {
703 	Arg	arg;
704 	char	*progstr;
705 	extern FILE	*disc_info;
706 
707 	disc_info = fopen(info_filename, "w+"); /* open for r/w */
708 	if (disc_info == NULL) {
709 		fprintf(stderr,"Can't open save file %s\n",info_filename);
710 		perror("cb_save_program");
711 		return;
712 	}
713 	fprintf(disc_info, "Title:%s\nProgram: %s\n", disc_title, program_str);
714 	fflush(disc_info);
715 
716 	debug_printf(1, "program saved to %s\n", info_filename);
717 }
718 
719 void
add_to_new_track(number)720 add_to_new_track (number)
721 int	number;
722 {
723 	Arg	arg;
724 	char	*namestr;
725 	int	track = 0;
726 
727 	/* an apparent bug in my system won't allow the auto-display of this
728 	 * label change without explicit forcing redraw via something other
729 	 * than the label itself
730 	 */
731 	XtSetArg(arg, XtNsensitive, False);
732 	XtSetValues(new_track_button, &arg, 1);
733 
734 	XtSetArg(arg, XtNlabel, &namestr);
735 	XtGetValues(new_track_button, &arg, 1);
736 	if (namestr[0] != ' ')
737 	    sscanf (namestr, "%d", &track);
738 	track += number;
739 	sprintf(namestr, "%d\n", track);
740 	XtSetArg(arg, XtNlabel, namestr);
741 	XtSetValues(new_track_button, &arg, 1);
742 
743 	/* reset the sensitive flage for redraw */
744 	XtSetArg(arg, XtNsensitive, True);
745 	XtSetValues(new_track_button, &arg, 1);
746 }
747 
748 static void
cb_add_10(widget,client_data,call_data)749 cb_add_10(widget, client_data, call_data)
750 Widget		widget;
751 XtPointer	client_data;
752 XtPointer	call_data;
753 {
754 	Arg	arg;
755 	char	*namestr;
756 	int	track = 0;
757 
758 	XtSetArg(arg, XtNsensitive, True);
759 	XtSetValues(new_track_button, &arg, 1);
760 	adding_to_new_track = True;
761 	add_to_new_track(10);
762 }
763 
764 static void
cb_new_track(widget,client_data,call_data)765 cb_new_track(widget, client_data, call_data)
766 Widget		widget;
767 XtPointer	client_data;
768 XtPointer	call_data;
769 {
770 	Arg	arg;
771 	char	*namestr;
772 	int	track;
773 
774 	XtSetArg(arg, XtNlabel, &namestr);
775 	XtGetValues(widget, &arg, 1);
776 	sscanf (namestr, "%d", &track);
777 
778 	if ((track >= cdi.mintrack) && (track <= cdi.maxtrack))
779 	{
780 	    debug_printf(1, "adding track %d to program\n", track);
781 	    program_add_track((unsigned char) track);
782 	}
783 	XtSetArg(arg, XtNlabel, "  ");
784 	XtSetValues(new_track_button, &arg, 1);
785 	XtSetArg(arg, XtNsensitive, False);
786 	XtSetValues(new_track_button, &arg, 1);
787 	adding_to_new_track = False;
788 }
789 
790 
791 static void
cb_trackbuttons(widget,client_data,call_data)792 cb_trackbuttons(widget, client_data, call_data)
793 Widget		widget;
794 XtPointer	client_data;
795 XtPointer	call_data;
796 {
797 	Arg	arg;
798 	char	*namestr;
799 	int	track;
800 	Boolean state;
801 
802 	XtSetArg(arg, XtNlabel, &namestr);
803 	XtGetValues(widget, &arg, 1);
804 	sscanf (namestr, "%d", &track);
805 
806 	if (adding_to_new_track)
807 	    add_to_new_track(track);
808 	else
809 	{
810 	    debug_printf(1, "adding track %d to program\n", track);
811 	    program_add_track((unsigned char) track);
812 	}
813 
814 }
815