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/Xaw/Form.h>
19 # include <X11/Xaw/Toggle.h>
20 
21 # include <stdio.h>
22 
23 # include "debug.h"
24 # include "cdrom_globs.h"
25 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
26 # include "cdrom_freebsd.h"
27 #endif
28 #ifdef sun
29 # include "cdrom_sun.h"
30 #endif
31 #ifdef sgi
32 # include "cdrom_sgi.h"
33 #endif
34 
35 extern AppData app_data;
36 
37 void		cdrom_new_disc();
38 
39 /*
40  * cb_cdrom_play checks to see if we're playing; if so do nothing.
41  * if not playing turns on playing.  if paused then return.
42  * otherwise start cd playing.
43  */
44 /*ARGSUSED*/
45 void
cb_cdrom_play(widget,client_data,call_data)46 cb_cdrom_play(widget, client_data, call_data)
47 	Widget		widget;
48 	XtPointer	client_data;
49 	XtPointer	call_data;
50 {
51 	if (cdrom_open() == -1) {
52 		debug_printf(1, "cb_cdrom_play: error from cdrom_open\n");
53 		/* Turn the play button back off */
54 		play_button_reset();
55 		eject_button_set();
56 		return;
57 	}
58 
59 	if (cdi.state & CDROM_STATE_EJECTED) {
60 		cdrom_new_disc(widget);
61 	}
62 
63 	/*
64 	 * toggle button weirdness; play and stop are radio toggles, ie. if
65 	 * you hit stop, and you are playing, play is supposed to stop, so
66 	 * toggle buttons automatically invoke the notify procedure of other
67 	 * members of a toggle group when another member of the toggle group
68 	 * is activated, before the requested notification takes place.
69 	 * The practical upshot of this is that this routine can be called
70 	 * even if you didn't press play, and so it really takes no action.
71 	 */
72 	if (cdi.state & CDROM_STATE_PLAY) {
73 		debug_printf(1, "cb_cdrom_play: already playing track %d\n",
74 			    cdi.curtrack);
75 		return;
76 	}
77 
78 	if (cdi.curtrack == 0) 	/* (no track selected) */
79 	{
80 	    cdi.curtrack = cdi.mintrack;
81 	    track_button_update();
82 	}
83 
84 	cdi.state |= CDROM_STATE_PLAY;
85 
86 	if (cdi.state & CDROM_STATE_PAUSE) {
87 		debug_printf(1, "cb_cdrom_play: paused on track %d\n",
88 			    cdi.curtrack);
89 		return;
90 	}
91 
92 	timer_fsecs = 0;
93 	cdi.duration = 0;
94 
95 	if (cdi.state & CDROM_STATE_SHUFFLE)
96 		cdi.curtrack = shuffle_next_track();
97 
98 	else if (cdi.state & CDROM_STATE_PROGRAM)
99 	{
100 	    if ((cdi.curtrack = program_resume()) == 0) {
101 
102 		/* cancel program */
103 		debug_printf(1, "cb_cdrom_play: cancelling program\n");
104 		program_cancel();
105 	    	cdi.curtrack = cdi.mintrack;
106 	    }
107 	    else {
108 		debug_printf(1, "cb_cdrom_play: resetting timer button\n");
109 	        timer_button_reset();
110 	    }
111 	}
112 
113 	if (cdrom_play() != -1) {
114 		cdi.state &= ~CDROM_STATE_STOP;
115 	}
116 
117 	timer_button_update();
118 }
119 
120 /*
121  * cb_cdrom_pause toggles pausing on or off.
122  */
123 /*ARGSUSED*/
124 void
cb_cdrom_pause(widget,client_data,call_data)125 cb_cdrom_pause(widget, client_data, call_data)
126 	Widget		widget;
127 	XtPointer	client_data;
128 	XtPointer	call_data;
129 
130 {
131 	if (cdrom_open() == -1) {
132 		debug_printf(1, "cb_cdrom_pause: error from cdrom_open\n");
133 		pause_button_reset();
134 		return;
135 	}
136 
137 #ifdef sgi
138 	if (cdrom_status() == CDROM_NO_STATUS) {
139 		cdi.state |= CDROM_STATE_EJECTED;
140 		buttons_reset();
141 		pause_button_reset();
142 		return;
143 	}
144 #endif
145 
146 	if (cdi.state & CDROM_STATE_EJECTED) {
147 		cdrom_new_disc(widget);
148 	}
149 
150 	if (cdi.state & CDROM_STATE_PAUSE) {
151 		cdi.state &= ~CDROM_STATE_PAUSE;
152 
153 		if (cdi.state & CDROM_STATE_PROGRAM)
154 			cdi.curtrack = program_resume();
155 
156 		else if (cdi.curtrack == 0) 	/* (no track selected) */
157 	    {
158 	        cdi.curtrack = cdi.mintrack;
159 	        track_button_update();
160 	    }
161 
162 		debug_printf(1, "cb_cdrom_pause: resuming track %d\n",
163 			    cdi.curtrack);
164 
165 		/*
166 		 * if we use next or prev after a pause we can't
167 		 * just resume but have to move to the track.
168 		 */
169 		if ((cdi.curtrack == cdrom_get_curtrack())  &&
170 		    (cdi.duration > 0))
171 		{
172 			if (cdrom_resume() != -1) {
173 				cdi.state &= ~CDROM_STATE_EJECTED;
174 				eject_button_reset();
175 				cdi.state &= ~CDROM_STATE_STOP;
176 			}
177 
178 			cdrom_timer_on();
179 
180 			return;
181 		}
182 
183 		if (cdrom_play() != -1) {
184 			cdi.state &= ~CDROM_STATE_EJECTED;
185 			eject_button_reset();
186 			cdi.state &= ~CDROM_STATE_STOP;
187 		}
188 
189 		return;
190 	}
191 
192 	cdi.state |= CDROM_STATE_PAUSE;
193 
194 	debug_printf(1, "cb_cdrom_pause: pausing on track %d\n",
195 		    cdi.curtrack);
196 
197 	if (cdrom_pause() != -1) {
198 		cdi.state &= ~CDROM_STATE_STOP;
199 		cdi.state |= CDROM_STATE_PLAY;
200 		eject_button_reset();
201 		play_button_set();
202 	}
203 
204 	cdrom_timer_off();
205 }
206 
207 /*
208  * cb_cdrom_stop checks to see if we're playing; if not then
209  * do nothing.  sets the current track to the first audio track.
210  * turns off play, pause, stops the cd, and closes it so that the
211  * disc can be ejected with the eject button on the drive.
212  */
213 /*ARGSUSED*/
214 void
cb_cdrom_stop(widget,client_data,call_data)215 cb_cdrom_stop(widget, client_data, call_data)
216 	Widget		widget;
217 	XtPointer	client_data;
218 	XtPointer	call_data;
219 {
220 	Arg	args[1];
221 	Boolean	state;
222 
223 	if (cdrom_open() == -1) {
224 		debug_printf(1, "cb_cdrom_stop: error from cdrom_open\n");
225 		/* Turn the stop button back off */
226 		stop_button_reset();
227 		eject_button_set();
228 		return;
229 	}
230 
231 #ifdef sgi
232 	if (cdrom_status() == CDROM_NO_STATUS) {
233 		cdi.state |= CDROM_STATE_EJECTED;
234 		buttons_reset();
235 		/* Turn the stop button back off */
236 		stop_button_reset();
237 		return;
238 	}
239 #endif
240 
241 	/* toggle button weirdness; see comment in cb_cdrom_play for details */
242 	XtSetArg(args[0], XtNstate, &state);
243 	XtGetValues(widget, args, 1);
244 
245 	if (state == False) {
246 		debug_printf(1, "cb_cdrom_stop: already stopped\n");
247 		return;
248 	}
249 
250 	debug_printf(1, "cb_cdrom_stop: resetting disc\n");
251 
252 	cdrom_reset();
253 
254 	if (cdi.state & CDROM_STATE_SHUFFLE) {
255 		debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
256 		cdi.state |= CDROM_STATE_SHUFFLE;
257 		shuffle_setup();
258 	}
259 }
260 
261 /*
262  * cb_cdrom_previous decrments the current track.  if paused or stopped
263  * then return.  otherwise start playing the (new) current track.
264  */
265 /*ARGSUSED*/
266 void
cb_cdrom_previous(widget,client_data,call_data)267 cb_cdrom_previous(widget, client_data, call_data)
268 	Widget		widget;
269 	XtPointer	client_data;
270 	XtPointer	call_data;
271 {
272 	if (cdrom_open() == -1) {
273 		debug_printf(1, "cb_cdrom_previous: error from cdrom_open\n");
274 		return;
275 	}
276 
277 #ifdef sgi
278 	if (cdrom_status() == CDROM_NO_STATUS) {
279 		cdi.state |= CDROM_STATE_EJECTED;
280 		buttons_reset();
281 		return;
282 	}
283 #endif
284 
285 	cdi.state &= ~CDROM_STATE_EJECTED;
286 	eject_button_reset();
287 	cdi.state &= ~CDROM_STATE_STOP;
288 
289 	cdrom_timer_off();
290 
291 	/*
292 	 * if playing less than replayThreshold seconds, back up to
293 	 * previous track; otherwise start at beginning of current track:
294 	 */
295 	if (cdi.duration < app_data.replayThreshold)
296 	{
297 	    if ((cdi.program != NULL) &&
298 	    	 (cdi.state & CDROM_STATE_PLAY) &&
299 		 ((cdi.state & CDROM_STATE_PAUSE) == 0))
300 	    {
301 	    	if (program_prev_track() == 0)
302 	            debug_printf(1, "cb_cdrom_previous: no previous selections in program\n");
303 	    	else
304 		{
305 	             debug_printf(1, "cb_cdrom_previous: going to prev selection\n");
306 		     cdi.curtrack = program_goto_prev_track();
307 		}
308 	    }
309 	    else if (cdi.curtrack > cdi.mintrack) /* can't go below 1st track:*/
310 	        cdi.curtrack--;
311 	}
312 
313 	timer_fsecs = 0;
314 	cdi.duration = 0;
315 
316 	if (cdi.state & CDROM_STATE_SHUFFLE)
317 		cdi.curtrack = shuffle_prev_track();
318 
319 	track_button_update();
320 	timer_button_update();
321 
322 	if (cdi.state & CDROM_STATE_PAUSE) {
323 		debug_printf(1, "cb_cdrom_previous: paused on track %d\n",
324 			    cdi.curtrack);
325 		if (cdrom_play() != -1) {
326 			cdi.state &= ~CDROM_STATE_STOP;
327 		}
328 		if (cdrom_pause() != -1) {
329 			cdi.state &= ~CDROM_STATE_STOP;
330 		}
331 		cdrom_timer_off();
332 		return;
333 	}
334 
335 	if ((cdi.state & CDROM_STATE_PLAY) == 0) {
336 		debug_printf(1, "cb_cdrom_previous: stopped on track %d\n",
337 			    cdi.curtrack);
338 		return;
339 	}
340 
341 	debug_printf(1, "cb_cdrom_previous: playing track %d\n",
342 		     cdi.curtrack);
343 
344 
345 	/* restart playing if not paused and currently playing */
346 	(void) cdrom_play();
347 }
348 
349 
350 /*
351  * cb_cdrom_next incrments the current track.  if paused or stopped
352  * then return.  otherwise start playing the (new) current track.
353  */
354 /*ARGSUSED*/
355 void
cb_cdrom_next(widget,client_data,call_data)356 cb_cdrom_next(widget, client_data, call_data)
357 	Widget		widget;
358 	XtPointer	client_data;
359 	XtPointer	call_data;
360 {
361 	if (cdrom_open() == -1) {
362 		debug_printf(1, "cb_cdrom_next: error from cdrom_open\n");
363 		return;
364 	}
365 
366 #ifdef sgi
367 	if (cdrom_status() == CDROM_NO_STATUS) {
368 		cdi.state |= CDROM_STATE_EJECTED;
369 		buttons_reset();
370 		return;
371 	}
372 #endif
373 
374 	if (cdi.state & CDROM_STATE_EJECTED) {
375 		cdrom_new_disc(widget);
376 	}
377 
378 	cdi.state &= ~CDROM_STATE_EJECTED;
379 	eject_button_reset();
380 	cdi.state &= ~CDROM_STATE_STOP;
381 
382 	if (cdi.state & CDROM_STATE_SHUFFLE) {
383 		if (cdi.currand == cdi.ntracks) {
384 			debug_printf(1, "cb_cdrom_next: at last track\n");
385 			return;
386 		}
387 	}
388 	else if ((cdi.program != NULL) &&
389 	    	 (cdi.state & CDROM_STATE_PLAY) &&
390 		 ((cdi.state & CDROM_STATE_PAUSE) == 0))
391 	{
392 	    if (program_next_track() == 0)
393 	        debug_printf(1, "cb_cdrom_next: no further selections in program\n");
394 	    else
395 	    {
396 	        debug_printf(1, "cb_cdrom_next: going to next selection\n");
397 	    	cdi.curtrack = program_goto_next_track();
398 	    }
399 	}
400 	else {
401 		if (cdi.curtrack >= cdi.maxtrack) {
402 			debug_printf(1, "cb_cdrom_next: at last track\n");
403 			return;
404 		}
405 		else
406 			cdi.curtrack++;
407 	}
408 
409 	cdrom_timer_off();
410 
411 	timer_fsecs = 0;
412 	cdi.duration = 0;
413 
414 
415 	track_button_update();
416 	timer_button_update();
417 
418 	if (cdi.state & CDROM_STATE_PAUSE) {
419 		debug_printf(1, "cb_cdrom_next: paused on track %d\n",
420 			    cdi.curtrack);
421 		if (cdrom_play() != -1) {
422 			cdi.state &= ~CDROM_STATE_STOP;
423 		}
424 		if (cdrom_pause() != -1) {
425 			cdi.state &= ~CDROM_STATE_STOP;
426 		}
427 		cdrom_timer_off();
428 		return;
429 	}
430 
431 	if ((cdi.state & CDROM_STATE_PLAY) == 0) {
432 		debug_printf(1, "cb_cdrom_next: stopped on track %d\n",
433 			    cdi.curtrack);
434 		return;
435 	}
436 
437 	if (cdi.state & CDROM_STATE_SHUFFLE)
438 		cdi.curtrack = shuffle_next_track();
439 
440 	debug_printf(1, "cb_cdrom_next: playing track %d\n",
441 		    cdi.curtrack);
442 
443 	/* restart playing if not paused and currently playing */
444 	(void) cdrom_play();
445 }
446 
447 
448 /*ARGSUSED*/
449 void
cb_cdrom_eject(widget,client_data,call_data)450 cb_cdrom_eject(widget, client_data, call_data)
451 	Widget		widget;
452 	XtPointer	client_data;
453 	XtPointer	call_data;
454 {
455 	Arg	args[1];
456 	Boolean	state;
457 
458 	if (cdrom_open() == -1) {
459 		debug_printf(1, "cb_cdrom_eject: error from cdrom_open\n");
460 		return;
461 	}
462 
463 #ifdef sgi
464 	if (cdrom_status() == CDROM_NO_STATUS) {
465 		cdi.state |= CDROM_STATE_EJECTED;
466 		buttons_reset();
467 		return;
468 	}
469 #endif
470 
471 	/* Check if this is just a toggle event.  If so, do nothing */
472 	XtSetArg(args[0], XtNstate, &state);
473 	XtGetValues(widget, args, 1);
474 	if (state == False) {
475 		return;
476 	}
477 
478 	/* toggle button weirdness; see comment in cb_cdrom_play for details */
479 	if (cdi.state & CDROM_STATE_EJECTED) {
480 		debug_printf(1, "cb_cdrom_eject: already ejected\n");
481 		return;
482 	}
483 
484 	debug_printf(1, "cb_cdrom_eject: ejecting on track %d\n",
485 		    cdi.curtrack);
486 
487 	cdrom_reset();
488 	cdi.maxtrack = 0;
489 
490 	program_cancel();
491 	cdrom_eject();
492 	cdi.state |= CDROM_STATE_EJECTED;
493 	cdrom_close();
494 
495 	disc_title = NODISCSTR;
496 	update_title();
497 }
498 
499 #ifdef sgi
500 /*ARGSUSED*/
501 void
cb_cdrom_audio(widget,client_data,call_data)502 cb_cdrom_audio(widget, client_data, call_data)
503 	Widget		widget;
504 	XtPointer	client_data;
505 	XtPointer	call_data;
506 {
507 	if (cdrom_open() == -1) {
508 		debug_printf(1, "cb_cdrom_audio: error from cdrom_open\n");
509 		return;
510 	}
511 
512 	if (cdi.state & CDROM_STATE_PLAY) {
513 		XBell(XtDisplay(widget), 100);
514 		if (cdi.scsi_audio) {
515 			audio_button_set();
516 		} else {
517 			audio_button_reset();
518 		}
519 		return;
520 	}
521 
522 	if (cdi.scsi_audio) {
523 		debug_printf(1, "cb_cdrom_audio: toggling audio off\n");
524 		cdrom_toggle_audio();
525 		audio_button_reset();
526 		return;
527 	}
528 
529 	/* Check if it's available before turning it on */
530 	if ( cdrom_audio_avail() ) {
531 		debug_printf(1, "cb_cdrom_audio: toggling audio on\n");
532 		cdrom_toggle_audio();
533 		audio_button_set();
534 		return;
535 	}
536 	XBell(XtDisplay(widget), 100);
537 	audio_button_reset();
538 }
539 #endif /* sgi */
540 
541 /*ARGSUSED*/
542 void
cb_cdrom_cycle(widget,client_data,call_data)543 cb_cdrom_cycle(widget, client_data, call_data)
544 	Widget		widget;
545 	XtPointer	client_data;
546 	XtPointer	call_data;
547 {
548 	if (cdi.state & CDROM_STATE_CYCLE) {
549 		debug_printf(1, "cb_cdrom_cycle: cycle off\n");
550 		cdi.state &= ~CDROM_STATE_CYCLE;
551 
552 		return;
553 	}
554 
555 	debug_printf(1, "cb_cdrom_cycle: cycle on\n");
556 	cdi.state |= CDROM_STATE_CYCLE;
557 }
558 
559 /*ARGSUSED*/
560 void
cb_cdrom_shuffle(widget,client_data,call_data)561 cb_cdrom_shuffle(widget, client_data, call_data)
562 	Widget		widget;
563 	XtPointer	client_data;
564 	XtPointer	call_data;
565 {
566 	if (cdi.state & CDROM_STATE_SHUFFLE) {
567 
568 		debug_printf(1, "cb_cdrom_shuffle: shuffle off\n");
569 		cdi.state &= ~CDROM_STATE_SHUFFLE;
570 
571 		return;
572 	}
573 
574 	if (cdi.state & CDROM_STATE_PLAY) {
575 		XBell(XtDisplay(widget), 100);
576 		shuffle_button_reset();
577 		return;
578 	}
579 
580 	if (cdi.state & CDROM_STATE_PROGRAM) {
581 		debug_printf(1, "cb_cdrom_shuffle: cancelling program\n");
582 		program_cancel();
583 	}
584 
585 	debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
586 	cdi.state |= CDROM_STATE_SHUFFLE;
587 	shuffle_setup();
588 }
589 
590 /*ARGSUSED*/
591 void
cb_cdrom_quit(widget,client_data,call_data)592 cb_cdrom_quit(widget, client_data, call_data)
593 	Widget		widget;
594 	XtPointer	client_data;
595 	XtPointer	call_data;
596 {
597 	debug_printf(1, "cb_cdrom_quit: bye\n");
598 
599 	cdrom_timer_off();
600 	cdrom_close();
601 
602 	exit(0);
603 }
604 
605 
606 /*ARGSUSED*/
607 void
cb_cdrom_rewind(widget,client_data,call_data)608 cb_cdrom_rewind(widget, client_data, call_data)
609 	Widget		widget;
610 	XtPointer	client_data;
611 	XtPointer	call_data;
612 {
613 	if (cdrom_open() == -1) {
614 		debug_printf(1, "cb_cdrom_rew: error from cdrom_open\n");
615 		return;
616 	}
617 
618 	if ((cdi.state & CDROM_STATE_PLAY) || (cdi.state & CDROM_STATE_PAUSE)) {
619 		debug_printf(1, "cb_cdrom_rew: moving backward in track %d\n",
620 			    cdi.curtrack);
621 
622 		cdrom_rewind();
623 	}
624 }
625 
626 
627 /*ARGSUSED*/
628 void
cb_cdrom_ff(widget,client_data,call_data)629 cb_cdrom_ff(widget, client_data, call_data)
630 	Widget		widget;
631 	XtPointer	client_data;
632 	XtPointer	call_data;
633 {
634 	if (cdrom_open() == -1) {
635 		debug_printf(1, "cb_cdrom_ff: error from cdrom_open\n");
636 		return;
637 	}
638 
639 
640 	if ((cdi.state & CDROM_STATE_PLAY) || (cdi.state & CDROM_STATE_PAUSE)) {
641 		debug_printf(1, "cb_cdrom_ff: moving forward in track %d\n",
642 			    cdi.curtrack);
643 
644 		cdrom_ff();
645 	}
646 }
647 
648 static Boolean pgmButtonUp = False;
649 
650 /*ARGSUSED*/
651 void
cb_cdrom_program(widget,topLevel,call_data)652 cb_cdrom_program(widget, topLevel, call_data)
653 	Widget		widget;
654 	Widget		topLevel;
655 	XtPointer	call_data;
656 {
657 	if (pgmButtonUp)
658 	{
659 	    track_button_reset();
660 	    pgm_button_set();
661 
662 	    /*
663              * have to keep track of button position internally, since toggle
664              * widgets screw up when you mess with their state programatically,
665              * in that if you set the state to false when notified on a button
666              * press, if you also notify on button release, the state is
667              * auto-reset to true prior to notification, so there is no
668              * longer any way to tell if it's a button release:
669              * THIS IS A HACK! (necessary, but *still* a hack.)
670              */
671             pgmButtonUp = False;
672 
673 	    return;
674 	}
675 
676 	if ((cdi.state & CDROM_STATE_PROGRAM) == 0)
677 	{
678 	    if (cdrom_open() == -1) {
679 		debug_printf(1, "cb_cdrom_play: error from cdrom_open\n");
680 		return;
681 	    }
682 	    if (cdi.state & CDROM_STATE_EJECTED) {
683 		    cdrom_new_disc(widget);
684 	    }
685 	    if (cdi.state & CDROM_STATE_SHUFFLE) {
686 	        debug_printf(1, "cb_cdrom_program: cancelling shuffle mode\n");
687 	        cdi.state &= ~CDROM_STATE_SHUFFLE;
688 		shuffle_button_reset();
689 	    }
690 	    cdi.state &= ~CDROM_STATE_EJECTED;
691 	    eject_button_reset();
692 	    cdi.state &= ~CDROM_STATE_STOP;
693 
694 	    debug_printf(1, "cb_cdrom_program: program on\n");
695 	    cdi.state |= CDROM_STATE_PROGRAM;
696 	    timer_button_set();
697 	    popup_program_form (widget, topLevel, call_data);
698             /*
699              * have to keep track of button position internally, since command
700              * widgets screw up if you mess with their state programatically:
701              */
702             pgmButtonUp = True;
703 	    return;
704 	}
705 
706 	if (((cdi.state & CDROM_STATE_PAUSE) ||
707 	     ((cdi.state & CDROM_STATE_PLAY) == 0)) &&
708 	    (cdi.curtrack != 0))
709 	{
710 	    /* indicate to user he's programmed a track: */
711 	    pgm_button_reset();
712 	    track_button_set();
713 	    timer_button_update();
714 
715 	    debug_printf(1, "cb_cdrom_program: adding track %d to program list\n",
716 		cdi.curtrack);
717 	    program_add_track (cdi.curtrack);
718 	}
719         /*
720          * have to keep track of button position internally, since command
721          * widgets screw up if you mess with their state programatically:
722          */
723         pgmButtonUp = True;
724 
725 }
726 
727 
728 void
cdrom_new_disc(widget)729 cdrom_new_disc(widget)
730 	Widget	widget;
731 {
732 	Arg	args[1];
733 	Boolean	state;
734 
735 	debug_printf(1, "cdrom_new_disc: resetting disc\n");
736 
737 	cdrom_reset();
738 
739 	cdi.state &= ~CDROM_STATE_EJECTED;
740 	eject_button_reset();
741 
742 	/* toggle button weirdness; see comment in cb_cdrom_play for details */
743 	XtSetArg(args[0], XtNstate, &state);
744 	XtGetValues(widget, args, 1);
745 	if (state == False) {
746 		XtSetArg(args[0], XtNstate, True);
747 		XtSetValues(widget, args, 1);
748 	}
749 
750 	if (cdi.state & CDROM_STATE_SHUFFLE) {
751 		debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
752 		cdi.state |= CDROM_STATE_SHUFFLE;
753 		shuffle_setup();
754 	}
755 }
756