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