1 /* Sound Player
2 
3    Copyright (C) 1997 by Woo-jae Jung */
4 
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8 
9 #include <stdio.h>
10 #include <unistd.h>
11 
12 #include "xsplay.h"
13 #include "panel.h"
OptionPanel(QWidget * parent,char * name)14 
15 #include <qapp.h>
16 #include <qbrush.h>
17 #include <qfiledlg.h>
18 #include <qkeycode.h>
19 #include <qmsgbox.h>
20 #include <qpainter.h>
21 #include <qpixmap.h>
22 
23 Panel *panel;
24 QApplication *mainwidget;
25 static bool errorflag=false;
26 static char *errorstring;
27 
28 #define BOXWIDTH        2
29 #define FONTSIZE        16
30 #define LABELHEIGHT     30
31 #define SONGNAME_X      5
32 #define SONGNAME_Y      35
33 #define SONGNAME_WIDTH  200
34 #define SONGNAME_HEIGHT LABELHEIGHT
35 
36 #define SONGMUSI_X      SONGNAME_X
37 #define SONGMUSI_Y      (SONGNAME_Y+SONGNAME_HEIGHT)
38 #define SONGMUSI_WIDTH  SONGNAME_WIDTH
39 #define SONGMUSI_HEIGHT SONGNAME_HEIGHT
40 
41 #define SONGPATH_X      SONGNAME_X
42 #define SONGPATH_Y      (SONGMUSI_Y+SONGMUSI_HEIGHT)
43 #define SONGPATH_WIDTH  SONGNAME_WIDTH
44 #define SONGPATH_HEIGHT SONGNAME_HEIGHT
45 
46 #define FSTATUS_X       SONGPATH_X
47 #define FSTATUS_Y       (SONGPATH_Y+FONTSIZE)
48 #define FSTATUS_WIDTH   160
49 #define FSTATUS_HEIGHT  FONTSIZE
50 
51 #define FRAME_X         (FSTATUS_X+FSTATUS_WIDTH+10)
52 #define FRAME_Y         (FSTATUS_Y+2)
53 #define FRAME_WIDTH     (VOL_X-FRAME_X)
54 #define FRAME_HEIGHT    13
55 
56 
57 #define BUTTON_NUMBER   5
~OptionPanel()58 #define BUTTON_WIDTH    30
59 #define BUTTON_HEIGHT   20
60 #define BUTTONS_X       5
61 #define BUTTONS_Y       (FSTATUS_Y+FSTATUS_HEIGHT+5)
62 #define BUTTONS_WIDTH   (BUTTON_WIDTH*BUTTON_NUMBER)
63 
64 #define SONGNUM_X       (BUTTONS_X+BUTTONS_WIDTH+10)
65 #define SONGNUM_Y       BUTTONS_Y
66 #define SONGNUM_WIDTH   80
67 #define SONGNUM_HEIGHT  20
68 
69 #define STATUS_X        (SONGNAME_X+SONGNAME_WIDTH+10)
70 #define STATUS_Y        SONGNAME_Y
71 #define STATUS_WIDTH    100
72 #define STATUS_HEIGHT   40
73 
74 #define VOL_X           (STATUS_X+STATUS_WIDTH+10)
75 #define VOL_Y           SONGNAME_Y
76 #define VOL_WIDTH       15
77 #define VOL_HEIGHT      (PANEL_HEIGHT-35)
78 
79 #define PANEL_WIDTH    (VOL_X+VOL_WIDTH+20)
80 #define PANEL_HEIGHT   (BUTTONS_Y+BUTTON_HEIGHT)
81 
82 Panel::Panel(QWidget *parent,const char *name) : QWidget(parent,name)
83 {
84   resize(PANEL_WIDTH,PANEL_HEIGHT);
85   setFixedSize(PANEL_WIDTH,PANEL_HEIGHT);
86   setCaption(PACKAGE " " VERSION);
87 
88   {
89     menu=new QMenuBar(this,"menu");
90     QPopupMenu *file=new QPopupMenu;
91     QPopupMenu *option=new QPopupMenu;
92     CHECK_PTR(file);
93     menu->insertItem("&File",file);
94 
95     file->insertItem("Open",     this,SLOT(load()),    ALT+Key_O);
96     file->insertItem("Open List",this,SLOT(loadlist()),ALT+Key_L);
97     file->insertSeparator();
98     file->insertItem("Restart"  ,this,SLOT(restart()),ALT+Key_R);
99     file->insertSeparator();
100     file->insertItem("Quit",     this,SLOT(quit()),    ALT+Key_Q);
101 
102     menu->insertItem("&Option",option);
103 
104     option->insertItem("Setting",this,SLOT(option()),  ALT+Key_S);
105   }
106 
107   {
108     currentsong.name.w=new QLabel(this,"name");
109     currentsong.name.w->setGeometry(SONGNAME_X,SONGNAME_Y,
110 				  SONGNAME_WIDTH,SONGNAME_HEIGHT);
111     currentsong.name.w->setFrameStyle(QFrame::Box | QFrame::Raised);
112     currentsong.name.w->setLineWidth(BOXWIDTH);
113     currentsong.name.w->setFont(QFont("Times",16,QFont::Bold));
114     currentsong.name.w->setAlignment(AlignLeft);
115 
116     currentsong.musican.w=new QLabel(this,"musican");
117     currentsong.musican.w->setGeometry(SONGMUSI_X,SONGMUSI_Y,
118 				  SONGMUSI_WIDTH,SONGMUSI_HEIGHT);
119     currentsong.musican.w->setFrameStyle(QFrame::Box | QFrame::Raised);
120     currentsong.musican.w->setLineWidth(BOXWIDTH);
121     currentsong.musican.w->setFont(QFont("Times",16,QFont::Bold));
122     currentsong.musican.w->setAlignment(AlignLeft);
123 
124     currentsong.path.w=new QLabel(this,"path");
125     currentsong.path.w->setGeometry(SONGPATH_X,SONGPATH_Y,
126 				  SONGPATH_WIDTH,SONGPATH_HEIGHT);
127     currentsong.path.w->setAlignment(AlignLeft);
128 
129 
130     currentsong.number.w=new QLabel(this,"number");
131     currentsong.number.w->setGeometry(SONGNUM_X,SONGNUM_Y,
132 				    SONGNUM_WIDTH,SONGNUM_HEIGHT);
133     currentsong.number.w->setFont(QFont("Times",16,QFont::Bold));
134     currentsong.number.w->setAlignment(AlignLeft);
135 
136     currentstatus.w=new QLabel(this,"status");
137     currentstatus.w->setGeometry(STATUS_X,STATUS_Y,
138 			       STATUS_WIDTH,STATUS_HEIGHT);
139     currentstatus.w->setFont(QFont("Times",10));
140     currentstatus.w->setAlignment(AlignLeft);
141 
142     framestatus.w=new QLabel(this,"Framestatus");
143     framestatus.w->setGeometry(FSTATUS_X,FSTATUS_Y,
144 			     FSTATUS_WIDTH,FSTATUS_HEIGHT);
145     framestatus.w->setFont(QFont("Times",12));
146     framestatus.w->setAlignment(AlignLeft);
147   }
148 
149   {
150     QPainter p;
151     QPixmap  t(30,20);
152     QBrush   brush(black);
153     int i;
154 
155     t.fill(backgroundColor());
156     p.begin(&t);
157       for(i=0;i<=5;i++)
158       {
159 	p.drawLine(10,10,25, 5+i);
160 	p.drawLine(10,10,25,15-i);
161       }
162       p.fillRect( 8, 3, 2,14,brush);
163       p.fillRect( 4, 3, 2,14,brush);
164     p.end();
165     previousbutton=new QPushButton("Previous",this);
166     previousbutton->setGeometry(BUTTONS_X+BUTTON_WIDTH*0,BUTTONS_Y,
167 				BUTTON_WIDTH,BUTTON_HEIGHT);
168     previousbutton->setPixmap(t);
169     QObject::connect(previousbutton,SIGNAL(clicked()),this,SLOT(previous()));
170 
171     t.fill(backgroundColor());
172     p.begin(&t);
173     p.fillRect(10,5,10,10,brush);
174     p.end();
175     stopbutton=new QPushButton("Stop",this);
176     stopbutton->setGeometry(BUTTONS_X+BUTTON_WIDTH*1,BUTTONS_Y,
177 				BUTTON_WIDTH,BUTTON_HEIGHT);
178     stopbutton->setPixmap(t);
179     QObject::connect(stopbutton,SIGNAL(clicked()),this,SLOT(stop()));
180 
181     t.fill(backgroundColor());
182     p.begin(&t);
183       for(i=0;i<=5;i++)
184       {
185 	p.drawLine(5, 5+i,25,10);
186 	p.drawLine(5,15-i,25,10);
187       }
188     p.end();
189     playbutton=new QPushButton("Play",this);
190     playbutton->setGeometry(BUTTONS_X+BUTTON_WIDTH*2,BUTTONS_Y,
191 				BUTTON_WIDTH,BUTTON_HEIGHT);
192     playbutton->setPixmap(t);
193     QObject::connect(playbutton,SIGNAL(clicked()),this,SLOT(play()));
194 
195     t.fill(backgroundColor());
196     p.begin(&t);
197       p.fillRect(10,3,3,14,brush);
198       p.fillRect(17,3,3,14,brush);
199     p.end();
200     pausebutton=new QPushButton("Pause",this);
201     pausebutton->setGeometry(BUTTONS_X+BUTTON_WIDTH*3,BUTTONS_Y,
202 				BUTTON_WIDTH,BUTTON_HEIGHT);
203     pausebutton->setPixmap(t);
204     QObject::connect(pausebutton,SIGNAL(clicked()),this,SLOT(pause()));
205 
206     t.fill(backgroundColor());
207     p.begin(&t);
208       for(i=0;i<=5;i++)
209       {
210 	p.drawLine(5, 5+i,20,10);
211 	p.drawLine(5,15-i,20,10);
212       }
213 
214       p.fillRect(20, 3, 2,14,brush);
215       p.fillRect(24, 3, 2,14,brush);
216     p.end();
217     nextbutton=new QPushButton("Previous",this);
218     nextbutton->setGeometry(BUTTONS_X+BUTTON_WIDTH*4,BUTTONS_Y,
219 				BUTTON_WIDTH,BUTTON_HEIGHT);
220     nextbutton->setPixmap(t);
221     QObject::connect(nextbutton, SIGNAL(clicked()), this, SLOT(next()) );
222   }
223 
224   {
225     volume_slider=new QSlider(QSlider::Vertical,this,"Slider");
226     volume_slider->setTickmarks(QSlider::Below);
227     volume_slider->setGeometry(width()-20,32,
228 			       VOL_WIDTH,VOL_HEIGHT);
229     volume_slider->setValue(99-Setvolume(-1));
230     connect(volume_slider,SIGNAL(valueChanged(int)),
231 	    SLOT(Volumechanged(int)) );
232 
233     frame_slider.w=new QSlider(0,MAXFRAMESLIDER,0,0,
234 			     QSlider::Horizontal,this,"FSlider");
235     frame_slider.w->setTickmarks(QSlider::NoMarks);
236     frame_slider.w->setGeometry(FRAME_X,FRAME_Y,
237 			      FRAME_WIDTH,FRAME_HEIGHT);
238     frame_slider.w->setValue(0);
239     connect(frame_slider.w,SIGNAL(sliderMoved(int)),
240 	    SLOT(Framechanged(int)) );
241   }
242 
243   initializelabelflag=false;
244   initializelabel();
245 
246   timer=startTimer(200);
247 }
248 
249 inline void refreshlabel(Label *l)
250 {
251   if(l->dirty)
252   {
253     l->dirty=false;
254     l->w->setText(l->str);
255   }
256 }
257 
258 void Panel::Setframeslider(int frame,int maxframe)
259 {
260   if(maxframe>1)
261     frame_slider.w->setValue(getslidernumber(frame,maxframe));
262 }
263 
264 void Panel::initializelabel(void)
265 {
266   currentsong.name.str   =
267   currentsong.musican.str=
268   currentsong.number.str =nullstring;
269   currentsong.path.str   =nonestring;
270   currentstatus.str      =
271   framestatus.str        =stopstring;
272   refreshflag=true;
273 }
274 
275 void Panel::timerEvent(QTimerEvent *)
276 {
277   if(initializelabelflag)
278   {
279     initializelabel();
280     initializelabelflag=false;
281   }
282 
283   if(refreshflag)
284   {
285     refreshflag=false;
286     updateflag=true;
287     if(errorflag)
288     {
289       char str[250];
290       QMessageBox mb;
291 
292       sprintf(str,"xsplay: %s",errorstring);
293 
294       mb.setText(str);
295       mb.setButtonText(0, "Skip");
296       mb.show();
297 
298       errorflag=false;
299     }
300     refreshlabel(&currentsong.path);
301     refreshlabel(&currentsong.number);
302     refreshlabel(&currentsong.name);
303     refreshlabel(&currentsong.musican);
304     refreshlabel(&currentstatus);
305   }
306 
307   if(updateflag)
308   {
309     updateflag=false;
310     refreshlabel(&framestatus);
311   }
312 
313   if(frame_slider.dirty)
314   {
315     if(!frame_slider.lock)
316     {
317       frame_slider.dirty=false;
318       Setframeslider(frame_slider.frame,frame_slider.maxframe);
319     }
320   }
321   doneflag=true;
322 }
323 
324 
325 
326 
327 void Panel::load()
328 {
329   extern void RunFileSelect(QWidget *widget);
330 
331   RunFileSelect(this);
332 }
333 
334 void Panel::loadlist()
335 {
336   QString fn = QFileDialog::getOpenFileName();
337   if(!fn.isEmpty())
338   {
339     stop();
340     readlist((char *)((const char *)fn));
341     music_restart();
342   }
343 }
344 
345 void Panel::restart()
346 {
347   music_stop();
348   music_restart();
349 }
350 
351 void Panel::quit()
352 {
353   exit(0);
354 }
355 
356 void Panel::option()
357 {
358   extern void RunOptionPanel(QWidget *widget);
359 
360   RunOptionPanel(this);
361 }
362 
363 void Panel::stop()
364 {
365   music_stop();
366 }
367 
368 void Panel::play()
369 {
370   music_play();
371 }
372 
373 void Panel::pause()
374 {
375   music_pause();
376 }
377 
378 void Panel::previous()
379 {
380   music_previous();
381 }
382 
383 void Panel::next()
384 {
385   music_next();
386 }
387 
388 void Panel::Volumechanged(int value)
389 {
390   int vol;
391 
392   vol=99-Setvolume(99-value);
393 
394   volume_slider->setValue(vol);
395 }
396 
397 void Panel::Framechanged(int frame)
398 {
399   frame_slider.lock=true;
400   Setframe(frame);
401 }
402 
403 
404 /*********************/
405 /* Interface routine */
406 /*********************/
407 void Displayerror(char *errstr)
408 {
409   errorstring=errstr;
410   errorflag=true;
411   panel->refreshflag=true;
412 }
413 
414 bool Msgboxdone(void)
415 {
416   return !errorflag;
417 }
418 
419 inline void Setlabel(Label *l,const char *name)
420 {
421   l->str=name;
422   l->dirty=true;
423 }
424 
425 void Setsongname(const char *name)
426 {
427   if(name[0])Setlabel(&(panel->currentsong.name),name);
428   panel->refreshflag=true;
429 }
430 
431 void Setsongmusican(const char *musican)
432 {
433   Setlabel(&(panel->currentsong.musican),musican);
434   panel->refreshflag=true;
435 }
436 
437 void Setsongpath(const char *path)
438 {
439   Setlabel(&(panel->currentsong.name),nullstring);
440   Setlabel(&(panel->currentsong.path),path);
441   Setsongmusican(nullstring);
442 }
443 
444 void Setcurrentsongnumber(int crun,int no)
445 {
446   if(crun>=no)
447     Setlabel(&(panel->currentsong.number),"END");
448   else
449   {
450     sprintf(panel->cbuffer.number,"%d/%d",crun+1,no);
451     Setlabel(&(panel->currentsong.number),panel->cbuffer.number);
452   }
453 
454   panel->refreshflag=true;
455 }
456 
457 void Setcurrentmpegstatus(int version,int layer,
458 			  int frequency,int bitrate,
459 			  bool crc,int mode,
460 			  bool forcetomono,int downfreq)
461 {
462   if(music_isstop())
463     Setlabel(&(panel->currentstatus),nullstring);
464   else
465   {
466     sprintf(panel->cbuffer.status,
467 	    "MPEG-%d, Layer %d\n"
468             "%5.2fKHz%s, "
469 	    "%dkbps\n"
470 	    "%s, "
471 	    "%s%s",
472 	    version+1,layer,
473 	    (float)frequency/1000.,downfreq ? "//2" : "",
474 	    bitrate,
475 	    (crc ? "Crc" : "No Crc"),
476 	    (mode ? "Stereo" : "Mono"),
477 	    forcetomono ? "(M)" : "");
478     Setlabel(&(panel->currentstatus),panel->cbuffer.status);
479   }
480   panel->refreshflag=true;
481 }
482 
483 void Clearcurrentstatus(void)
484 {
485   Setlabel(&(panel->currentstatus),nullstring);
486   panel->refreshflag=true;
487 }
488 
489 void Setframestatus(int frame,int maxframe,
490 		    int pcmperframe,int frequency)
491 {
492   if(music_isstop())
493     Setlabel(&(panel->framestatus),stopstring);
494   else
495   {
496     int m,s,mm,ms;
497 
498     s=frame*pcmperframe/frequency;
499     m=s/60;s=s%60;
500     if(maxframe==0)
501       sprintf(panel->cbuffer.framestatus,"%2d:%2d",m,s);
502     else
503     {
504       ms=maxframe*pcmperframe/frequency;
505       mm=ms/60;ms=ms%60;
506       sprintf(panel->cbuffer.framestatus,
507 	      "%2d:%2d(%2d:%2d)",m,s,mm,ms);
508     }
509     Setlabel(&(panel->framestatus),panel->cbuffer.framestatus);
510   }
511 
512   if(maxframe)
513   {
514     panel->frame_slider.frame=frame;
515     panel->frame_slider.maxframe=maxframe;
516     panel->frame_slider.dirty=true;
517   }
518   panel->updateflag=true;
519 }
520 
521 void Unlockframeslider(void)
522 {
523   panel->frame_slider.lock=false;
524 }
525 
526 void Paneldone(void)
527 {
528   panel->doneflag=false;
529   panel->initializelabelflag=true;
530   while(!panel->doneflag)usleep(100);
531   while(panel->initializelabelflag)usleep(100);
532 }
533 
534 int mainwidget_x(void)
535 {
536   return panel->x();
537 }
538 
539 int mainwidget_y(void)
540 {
541   return panel->y();
542 }
543 
544 
545 
546 void Getxarg(int &argc,char *argv[])
547 {
548   mainwidget=new QApplication(argc,argv);
549 }
550 
551 void SetupPanel(void)
552 {
553 #ifdef USE_KOREAN
554   {
555     extern void Koreaninit(void);
556     Koreaninit();
557   }
558 #endif
559   panel=new Panel;
560   mainwidget->setMainWidget(panel);
561   panel->show();
562   QObject::connect(mainwidget,SIGNAL(lastWindowClosed()),
563 		   mainwidget,SLOT(quit()) );
564 }
565 
566 int RunPanel(void)
567 {
568   return mainwidget->exec();
569 }
570