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/Command.h>
22 # include <X11/Xaw/Toggle.h>
23 # include <X11/Xaw/Scrollbar.h>
24 # include <X11/Xaw/Dialog.h>
25 # include <X11/Xaw/Viewport.h>
26 
27 # include <math.h>
28 # include <stdio.h>
29 
30 # include "cdrom_globs.h"
31 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
32 # include "cdrom_freebsd.h"
33 #endif
34 #ifdef sun
35 # include "cdrom_sun.h"
36 #endif
37 #ifdef sgi
38 # include "cdrom_sgi.h"
39 #endif
40 
41 # include "logo.xbm"
42 # include "thumb.xbm"
43 # include <X11/bitmaps/gray>
44 
45 # define MAXVOL		0xff
46 
47 void	Done();
48 
49 extern AppData app_data;
50 
51 static Widget	track_button_widget;
52 static Widget	timer_button_widget;
53 static Widget	volume_scroll_widget;
54 
55 Widget		title_viewport;
56 Widget		title_form;
57 Widget		title_button;
58 Widget		title_dialog_shell;
59 Widget		title_dialog_widget;
60 Widget		title_done_widget;
61 
62 static int	vol;
63 extern void     leds_label_setup();
64 static void     cb_track_button();
65 static void     cb_timer_button();
66 static void     volume_jump_proc();
67 static void     volume_scroll_proc();
68 static void     popup_title_dialog();
69 static void     popdown_title_dialog();
70 
71 
72 void
logo_setup(parent_widget)73 logo_setup(parent_widget)
74 	Widget		parent_widget;
75 {
76 	Widget		version_label_widget;
77 	char		version_string[80];
78 
79 	Widget		logo_form_widget;
80 	Widget		logo_label_widget;
81 	Pixmap		logo_label_pixmap;
82 	Pixmap		thumb_pixmap;
83 	Pixmap		gray;
84 	int			depth;
85 	int		length;
86 
87 
88 	Arg		args[4];
89 	static XtActionsRec	done[] = {
90 		{"done", Done},
91 	};
92 
93 
94 	logo_form_widget = XtCreateManagedWidget("logoForm", formWidgetClass,
95 						 parent_widget,
96 						 (ArgList) NULL, 0);
97 
98 	logo_label_widget = XtCreateManagedWidget("logoLabel",
99 						  labelWidgetClass,
100 						  logo_form_widget,
101 						  (ArgList) NULL, 0);
102 
103 	logo_label_pixmap = XCreateBitmapFromData(XtDisplay(logo_label_widget),
104 						  rootwin(logo_label_widget),
105 						  logo_bits,
106 						  logo_width, logo_height);
107 
108 	sprintf(version_string,"XCdplayer %s%d",VERSION,PATCHLEVEL);
109 	if (BETA != 0) {
110 		sprintf(version_string,"%s beta %d",version_string,BETA);
111 	}
112 	XtSetArg(args[0], XtNjustify, XtJustifyRight);
113 	XtSetArg(args[1], XtNlabel, version_string);
114 	version_label_widget = XtCreateManagedWidget("versionLabel",
115 						     labelWidgetClass,
116 						     logo_form_widget,
117 						     (ArgList) args, 2);
118 
119 	XtSetArg(args[0], XtNbitmap, logo_label_pixmap);
120 	XtSetValues(logo_label_widget, args, 1);
121 
122 	leds_label_setup(logo_form_widget);
123 
124 
125 	track_button_widget = XtCreateManagedWidget("trackButton",
126 						    toggleWidgetClass,
127 						    logo_form_widget,
128 						    (ArgList) NULL, 0);
129 
130 	XtAddCallback(track_button_widget, XtNcallback, cb_track_button, 0);
131 
132 	track_button_update();
133 
134 	if (app_data.display_timer == True) {
135 		timer_button_widget = XtCreateManagedWidget("timerButton",
136 						    	   toggleWidgetClass,
137 							   logo_form_widget,
138 							   (ArgList) NULL, 0);
139 
140 		XtAddCallback(timer_button_widget, XtNcallback,
141 			     cb_timer_button, 0);
142 		timer_button_update();
143 	}
144 	thumb_pixmap = XCreateBitmapFromData(XtDisplay(logo_form_widget),
145 						  rootwin(logo_form_widget),
146 						  thumb_bits,
147 						  thumb_width, thumb_height);
148 
149     XtSetArg (args[0], XtNdepth, &depth);
150     XtGetValues (logo_form_widget, args, 1);
151 
152 	if (depth == 1) {
153 	    gray = XCreateBitmapFromData(XtDisplay(logo_form_widget),
154 						  rootwin(logo_form_widget),
155 						  gray_bits,
156 						  gray_width, gray_height);
157 
158 	    XtSetArg(args[0], XtNbackgroundPixmap, gray);
159 	    XtSetArg(args[1], XtNthumb, thumb_pixmap);
160 	    volume_scroll_widget = XtCreateManagedWidget("volumeScrollbar",
161 						     scrollbarWidgetClass,
162 						     logo_form_widget,
163 						     (ArgList) args, 2);
164 	}
165 	else
166 	{
167 	     /*XtSetArg(args[0], XtNthumb, thumb_pixmap);*/
168 
169 	     volume_scroll_widget = XtCreateManagedWidget("volumeScrollbar",
170 						     scrollbarWidgetClass,
171 						     logo_form_widget,
172 						     (ArgList) args, 0);
173 	}
174 
175 	XtAddCallback(volume_scroll_widget, XtNjumpProc, volume_jump_proc, 0);
176 	XtAddCallback(volume_scroll_widget, XtNscrollProc, volume_scroll_proc, 0);
177 
178 #ifdef sgi
179 	if ((vol = cdrom_get_volume()) == 0) {
180 		vol = (int) ((MAXVOL - app_data.volbase) * 0.75) + app_data.volbase;
181 	}
182 #else
183 	vol = (int) ((MAXVOL - app_data.volbase) * 0.75) + app_data.volbase;
184 #endif
185 	cdrom_volume(vol, vol);
186 #ifdef sgi
187 	XawScrollbarSetThumb(volume_scroll_widget,
188 			     (float) (VAL2PCT(vol)),
189 			     (float) 1.0);
190 #else
191 	XawScrollbarSetThumb(volume_scroll_widget, (float) 0.75, (float) 1.0);
192 #endif
193 
194 	title_viewport = XtCreateManagedWidget ("titleBarViewport",
195 				viewportWidgetClass,
196 				logo_form_widget,
197 				(ArgList) NULL, 0);
198 
199 	title_form = XtCreateManagedWidget ("titleForm",
200 				formWidgetClass,
201 				title_viewport,
202 				(ArgList) NULL, 0);
203 
204 	if (disc_title != NULL)
205         	XtSetArg(args[0], XtNlabel, disc_title);
206 	else
207 #ifdef sgi
208 		if (cdrom_status() == CDROM_NO_STATUS) {
209 			XtSetArg(args[0], XtNlabel, NODISCSTR);
210 		} else {
211 			XtSetArg(args[0], XtNlabel, NOTITLESTR);
212 		}
213 #else
214 		XtSetArg(args[0], XtNlabel, NOTITLESTR);
215 #endif
216 
217 	title_button = XtCreateManagedWidget ("titleBar",
218 				commandWidgetClass,
219 				title_form,
220 				(ArgList) args, 1);
221 
222 	title_dialog_shell = XtCreatePopupShell("titleShell",
223 				transientShellWidgetClass,
224 				title_button,
225 				(ArgList) NULL, 0);
226 
227         XtSetArg(args[0], XtNlabel, "Title: ");
228         title_dialog_widget = XtCreateManagedWidget("titleDialog",
229                                 	dialogWidgetClass,
230                                 	title_dialog_shell,
231                                 	(ArgList) args, 1);
232 
233 	title_done_widget = XtCreateManagedWidget("Done",
234 					commandWidgetClass,
235 					title_dialog_widget,
236 					(ArgList) NULL, 0);
237 
238 	XtAppAddActions(appc, done, XtNumber(done));
239 
240 	XtAddCallback(title_button, XtNcallback, popup_title_dialog,
241 			(XtPointer) logo_form_widget);
242 	XtAddCallback(title_done_widget, XtNcallback, popdown_title_dialog,
243 			(XtPointer) title_dialog_widget);
244 
245 
246 }
247 
248 /*ARGSUSED*/
249 static void
cb_track_button(widget,client_data,call_data)250 cb_track_button(widget, client_data, call_data)
251 	Widget		widget;
252 	XtPointer	client_data;
253 	XtPointer	call_data;
254 {
255 	char		track_buf[40];
256 	Arg		args[1];
257 	Boolean		state;
258 
259 	XtSetArg(args[0], XtNstate, &state);
260 	XtGetValues(widget, args, 1);
261 
262 #ifdef sgi
263 	if (cdrom_status() == CDROM_NO_STATUS) {
264 		cdi.state |= CDROM_STATE_EJECTED;
265 		buttons_reset();
266 		return;
267 	}
268 #endif
269 
270 	if (cdi.state & CDROM_STATE_EJECTED) {
271 		cdrom_new_disc();
272 	}
273 
274 	if (state == True)
275 		sprintf(track_buf, "%d\n", cdi.maxtrack);
276 	else
277 		sprintf(track_buf, "%d\n", cdi.curtrack);
278 
279 	XtSetArg(args[0], XtNlabel, track_buf);
280 	XtSetValues(widget, args, 1);
281 }
282 
283 void
track_button_update()284 track_button_update() {
285 	char		track_buf[40];
286 	Arg		args[1];
287 
288 	sprintf(track_buf, "%d\n", cdi.curtrack);
289 
290 	XtSetArg(args[0], XtNlabel, track_buf);
291 	XtSetValues(track_button_widget, args, 1);
292 }
293 
294 static void
cb_timer_button(widget,client_data,call_data)295 cb_timer_button(widget, client_data, call_data)
296 	Widget		widget;
297 	XtPointer	client_data;
298 	XtPointer	call_data;
299 {
300 	char		timer_buf[40];
301 	int		time_remaining;
302 	Arg		args[1];
303 	Boolean		state;
304 
305 	if (cdi.state & CDROM_STATE_EJECTED) {
306 		cdrom_new_disc();
307 	}
308 
309 #ifdef sgi
310 	if (cdrom_status() == CDROM_NO_STATUS) {
311 		cdi.state |= CDROM_STATE_EJECTED;
312 		buttons_reset();
313 		return;
314 	}
315 #endif
316 
317 	cdi.duration = cdrom_get_curtime();
318 
319 	XtSetArg(args[0], XtNstate, &state);
320 	XtGetValues(widget, args, 1);
321 
322 	if ((state == True) && (cdi.curtrack != 0))
323 	{
324 	    if (((cdi.state & CDROM_STATE_PAUSE) == 0) &&
325 	        (cdi.state & CDROM_STATE_PROGRAM))
326 	    {
327 	        time_remaining = program_time_remaining();
328 	    }
329 	    else
330 	        time_remaining = cdi.times[cdi.curtrack - 1] - cdi.duration;
331 
332 	    if (time_remaining < 0)
333 	        sprintf(timer_buf, "-%02u:%02u\n",abs(time_remaining) / 60,
334 		    abs(time_remaining) % 60);
335 	    else
336 	        sprintf(timer_buf, "-%02d:%02d\n", time_remaining / 60,
337 		    time_remaining % 60);
338 	} else if (cdi.curtrack != 0) {
339 		if (cdi.duration < 0)
340 			sprintf(timer_buf, "-%02u:%02u\n", cdi.duration / 60,
341 				abs(cdi.duration) % 60);
342 		else
343 			sprintf(timer_buf, "%02u:%02u\n", cdi.duration / 60,
344 				cdi.duration % 60);
345 	} else {
346 		if ((state == True) && (cdrom_status() != CDROM_NO_STATUS))
347 			sprintf(timer_buf, "-%02u:%02u\n",
348 				cdi.addrs[cdi.maxtrack].minute,
349 				cdi.addrs[cdi.maxtrack].second);
350 		else
351 			sprintf(timer_buf, "--:--\n");
352 	}
353 
354 	XtSetArg(args[0], XtNlabel, timer_buf);
355 	XtSetValues(widget, args, 1);
356 }
357 
358 void
timer_button_update()359 timer_button_update() {
360 	char		timer_buf[40];
361 	int		time_remaining;
362 	Arg		args[1];
363 	Boolean		state;
364 
365 	if (app_data.display_timer == False)
366 		return;
367 
368 	    if ((cdi.state & CDROM_STATE_PAUSE) == 0)
369 	        cdi.duration = cdrom_get_curtime();
370 
371 	    XtSetArg(args[0], XtNstate, &state);
372 	    XtGetValues(timer_button_widget, args, 1);
373 
374 	    if ((state == True) && (cdi.curtrack != 0))
375 	    {
376 		if (((cdi.state & CDROM_STATE_PAUSE) == 0) &&
377 		    (cdi.state & CDROM_STATE_PROGRAM))
378 		{
379 	            time_remaining = program_time_remaining();
380 		}
381 		else
382 	            time_remaining = cdi.times[cdi.curtrack - 1] - cdi.duration;
383 	        if (time_remaining < 0)
384 	            sprintf(timer_buf, "-%02u:%02u\n",abs(time_remaining) / 60,
385 		        abs(time_remaining) % 60);
386 	        else
387 	            sprintf(timer_buf, "-%02d:%02d\n", time_remaining / 60,
388 		        time_remaining % 60);
389 	    }
390 	    else if (cdi.state & CDROM_STATE_PLAY)
391 	    {
392 	        if (cdi.duration < 0)
393 	            sprintf(timer_buf, "-%02u:%02u\n", cdi.duration / 60,
394 		        abs(cdi.duration) % 60);
395 	        else
396 	            sprintf(timer_buf, "%02u:%02u\n", cdi.duration / 60,
397 		        cdi.duration % 60);
398 	    }
399 	    else
400 		if ((state == True) && (cdrom_status() != CDROM_NO_STATUS))
401 			sprintf(timer_buf, "-%02u:%02u\n",
402 				cdi.addrs[cdi.maxtrack].minute,
403 				cdi.addrs[cdi.maxtrack].second);
404 		else
405 			sprintf(timer_buf, "--:--\n");
406 
407 	XtSetArg(args[0], XtNlabel, timer_buf);
408 	XtSetValues(timer_button_widget, args, 1);
409 }
410 
411 static void
volume_jump_proc(scroll_widget,client_data,percent)412 volume_jump_proc(scroll_widget, client_data, percent)
413 	Widget		scroll_widget;
414 	XtPointer	client_data;
415 	XtPointer	percent;
416 {
417 #ifdef sgi
418 	/* The volume control on SGI is not linear, but is exponential */
419 	vol = PCT2VAL(*(float *)percent);
420 #else
421 	vol = (*(float *) percent) * MAXVOL;
422 	vol = (vol * app_data.volpcent) + app_data.volbase;
423 #endif
424 
425 	if (vol > MAXVOL)
426 		vol = MAXVOL;
427 	if (vol <= 0)
428 		vol = 1;
429 
430 	debug_printf(1, "volume=%u\n", (unsigned int) vol);
431 
432 	cdrom_volume(vol, vol);
433 }
434 
435 static void
volume_scroll_proc(scroll_widget,client_data,position)436 volume_scroll_proc(scroll_widget, client_data, position)
437 	Widget		scroll_widget;
438 	XtPointer	client_data;
439 	XtPointer	position;
440 {
441 	Arg		args[1];
442 	Dimension	length;
443 	float		top;
444 	double		abspos;
445 	double		percent;
446 	double		vdelta;
447 
448 	if ((abspos = (int) position) < 0)
449 		abspos = -abspos;
450 
451 	XtSetArg(args[0], XtNlength, &length);
452 	XtGetValues(scroll_widget, args, 1);
453 
454 	if (length <= 0)
455 		length = 1;
456 
457 	percent = abspos / (float) length;
458 
459 #ifdef sgi
460 	/* The volume control on SGI is not linear, but is exponential */
461 	if ((vdelta = ((VAL2PCT(vol)) * percent)) < (VAL2PCT(1))) {
462 		vdelta = (VAL2PCT(1));
463 	}
464 	if ((int) position < 0)
465 		vol = (PCT2VAL((VAL2PCT(vol)) - vdelta));
466 	else
467 		vol = (PCT2VAL((VAL2PCT(vol)) + vdelta));
468 #else
469 	if ((vdelta = (vol * percent)) < 1.0)
470 		vdelta = 1.0;
471 
472 	if ((int) position < 0)
473 		vol += vdelta;
474 	else
475 		vol -= vdelta;
476 #endif
477 
478 	if (vol > MAXVOL)
479 		vol = MAXVOL;
480 	if (vol <= 0)
481 		vol = 1;
482 
483 	debug_printf(1, "volume=%u\n", (unsigned int) vol);
484 
485 	cdrom_volume(vol, vol);
486 
487 #ifdef sgi
488 	XtSetArg (args[0], XtNlength, &length);
489 	XtGetValues (volume_scroll_widget, args, 1);
490 	XawScrollbarSetThumb(volume_scroll_widget,
491 			     (float) (VAL2PCT(vol)),
492 			     (float) -1.0);
493 #endif
494 	top = (double) vol / (double) MAXVOL;
495 
496 	XawScrollbarSetThumb(volume_scroll_widget, (float) top, (float) -1.0);
497 }
498 
499 void
track_button_set()500 track_button_set() {
501 	Arg             args[1];
502 
503 	XtSetArg(args[0], XtNstate, True);
504 	XtSetValues(track_button_widget, args, 1);
505 }
506 
507 void
track_button_reset()508 track_button_reset() {
509 	Arg             args[1];
510 
511 	XtSetArg(args[0], XtNstate, False);
512 	XtSetValues(track_button_widget, args, 1);
513 }
514 
515 void
timer_button_set()516 timer_button_set() {
517 	Arg             args[1];
518 
519 	XtSetArg(args[0], XtNstate, True);
520 	XtSetValues(timer_button_widget, args, 1);
521 }
522 
523 void
timer_button_reset()524 timer_button_reset() {
525 	Arg             args[1];
526 
527 	XtSetArg(args[0], XtNstate, False);
528 	XtSetValues(timer_button_widget, args, 1);
529 }
530 
531 
532 /*ARGSUSED*/
533 void
popup_title_dialog(widget,parent,call_data)534 popup_title_dialog(widget, parent, call_data)
535 Widget		widget;
536 Widget		parent;
537 XtPointer	call_data;
538 {
539 	Position x, y;
540 	Dimension width, height;
541 	Arg	args[2];
542 	Widget	value;
543 	char	non_null[256];
544 
545 
546 
547 	if (disc_title != NULL) {
548 		sscanf(disc_title, "%s", non_null);
549 
550 		if (strcmp ("", non_null) != 0)
551         		XtSetArg(args[0], XtNvalue, disc_title);
552 		else
553         	    XtSetArg(args[0], XtNvalue, "");
554 	}
555 	else
556         	XtSetArg(args[0], XtNvalue, "");
557 
558 	XtSetValues(title_dialog_widget, args, 1);
559 
560 	XtTranslateCoords (widget,
561 		(Position) 14,
562 		(Position) 14,
563 		&x, &y);
564 
565 	XtSetArg(args[0], XtNx, x);
566 	XtSetArg(args[1], XtNy, y);
567 	XtSetValues(title_dialog_shell, args, 2);
568 
569 	if ((value = XtNameToWidget(title_dialog_widget, "value")) != 0) {
570 	    XtSetArg(args[0], XtNwidth, &width);
571 	    XtGetValues(title_button, args, 1);
572 	    XtSetArg(args[0], XtNwidth, width);
573 	    XtSetValues(value, args, 1);
574 	}
575 
576 	/*XtSetSensitive (widget, FALSE); */
577 	XtPopup (title_dialog_shell, XtGrabNone);
578 
579 }
580 
581 void
Done(widget,event,params,num_params)582 Done(widget, event, params, num_params)
583 	Widget		widget;
584 	XButtonEvent	*event;
585 	String		*params;
586 	Cardinal	*num_params;
587 {
588 	Arg	args[2];
589 
590 	if (disc_title != NULL)
591 	    free(disc_title);
592 	disc_title = XawDialogGetValueString(title_dialog_widget);
593 	XtSetArg(args[0], XtNlabel, disc_title);
594 	XtSetValues(title_button, args, 1);
595 
596 	XtPopdown(title_dialog_shell);
597 	XtSetSensitive(title_button, TRUE);
598 }
599 
600 void
popdown_title_dialog(widget,dialog,call_data)601 popdown_title_dialog(widget, dialog, call_data)
602 Widget	widget;
603 Widget	dialog;
604 XtPointer call_data;
605 {
606 	Arg	args[2];
607 
608 	if (disc_title != NULL)
609 	    free(disc_title);
610 	disc_title = XawDialogGetValueString(dialog);
611 	XtSetArg(args[0], XtNlabel, disc_title);
612 	XtSetValues(title_button, args, 1);
613 
614 	XtPopdown(title_dialog_shell);
615 	XtSetSensitive(title_button, TRUE);
616 }
617 
618 void
update_title()619 update_title () {
620 	Arg		args[1];
621 	char	non_null[256];
622 
623 	if (title_button != NULL) {
624 #if 0
625 		if (disc_title != NULL) {
626 			sscanf(disc_title, "%s", non_null);
627 			if (strcmp ("", non_null) != 0)
628 				XtSetArg(args[0], XtNvalue, disc_title);
629 			else
630 				XtSetArg(args[0], XtNvalue, "");
631 		else
632 			XtSetArg(args[0], XtNvalue, "");
633 		}
634 
635 		XtSetArg(args[0], XtNvalue, disc_title);
636 		XtSetValues(title_button, args, 1);
637 		XtSetArg(args[0], XtNvalue, disc_title);
638 		XtSetValues(title_dialog_widget, args, 1);
639 #endif
640 		XtSetArg(args[0], XtNvalue, disc_title);
641 		XtSetValues(title_dialog_widget, args, 1);
642 		XtSetArg(args[0], XtNlabel, disc_title);
643 		XtSetValues(title_button, args, 1);
644 
645 	}
646 }
647 
648 #ifdef sgi
set_volume(vol)649 set_volume(vol)
650 	int	vol;
651 {
652 	XawScrollbarSetThumb(volume_scroll_widget,
653 			     (float) (VAL2PCT(vol)),
654 			     (float) 1.0);
655 }
656 #endif
657