/* A NCURSES/CDK TUI (Text User Interface) for MuSE * Copyright (C) 2002 Luca 'rubik' Profico * * This source code is free software; you can redistribute it and/or * modify it under the terms of the GNU Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * Please refer to the GNU Public License for more details. * * You should have received a copy of the GNU Public License along with * this source code; if not, write to: * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: ncurses_gui.cpp,v 1.1.1.1 2003/12/08 12:20:35 jaromil Exp $ * */ #include #include #include #include #include #include NCURSES_GUI::NCURSES_GUI(int argc, char **argv, Stream_mixer *mix) : GUI(argc, argv, mix) { version = strdup("MuSE"); status = strdup(" Status::"); minibox = strdup("xxxxxxxxxxxxxxx"); shortcuts = strdup(SHORTCUTS_HELP); activechan=0; setlabels(); //enc = (struct encdata *) malloc (sizeof(struct encdata)); connbox = new ConnectBox (_mix); } NCURSES_GUI::~NCURSES_GUI() { func ("NCURSES_GUI::~NCURSES_GUI"); func ("screen pointer = %p", f.screen()); func ("title label pointer: %p", title.label()); func ("statusbar label pointer: %p", statusbar.label()); func ("helpbar label pointer: %p", helpbar.label()); func ("opchan label pointer: %p", opchan.label()); warning ("screen objcnt: %d", f.objcnt()); /* avoids free mem space overwriting by registering * all channels on the screen before quit */ for (int i = 0; i<6; i++) { curs_chan[i].reg(); } free (minibox); free (version); free (status); free (shortcuts); connbox->erase(); } void NCURSES_GUI::refresh () { //int i; //setlabels (); /* for (i = 0; i < MAX_CHANNELS; i++) { if (i % 2 == 0) //tutti a sinistraaaa ehehhhhh chan[i].init (f.screen (), 1, i); else //e tutti a destra ohhohhhhh chan[i].init (f.screen (), f.width () / 2, i); } */ canupdate = false; setactivechan (activechan, 0); canupdate = true; warning ("screen pointer = %p", f.screen()); /* chan[0].show (); chan[1].show (); */ // setactivechan (0); f.refresh (); } void NCURSES_GUI::run() { int i; while(!quit) { //setdialogs(); connbox->setparm(); for (i=0;i< MAX_CHANNELS;i++) { if (i%2 == 0) { //tutti a sinistraaaa ehehhhhh curs_chan[i].init (f.screen(),1,i); } else { //e tutti a destra ohhohhhhh curs_chan[i].init (f.screen(), f.width()/2, i); } _mix->create_channel (i); curs_chan[i].unreg(); curs_chan[i].defparam(); } f.refresh(); canupdate = true; curs_chan[0].reg(); // curs_chan[0].show(); curs_chan[1].reg(); // curs_chan[1].show(); setactivechan (0); userinput(); wait(); } } void NCURSES_GUI::setlabels (void) { title.setscreen (f.screen()); title.box = TRUE; title.setparm(1,1,f.width() - 4,1); title.setvalue (version); //title.draw(); statusbar.setscreen (f.screen()); statusbar.box = TRUE; statusbar.setparm(16,f.height()-3,f.width()-19,1); statusbar.setvalue (status); statusbar.urhook (ACS_RTEE); statusbar.ulhook (ACS_TTEE); statusbar.llhook (ACS_BTEE); //statusbar.draw(); helpbar.setscreen (f.screen()); helpbar.box = TRUE; helpbar.setparm (1,f.height() -5, f.width() - 4, 1); helpbar.setvalue (shortcuts); helpbar.llhook (ACS_LTEE); helpbar.lrhook (ACS_RTEE); //helpbar.draw(); opchan.setscreen (f.screen()); opchan.box=TRUE; opchan.setparm (1, f.height() -3, 15, 1); opchan.ulhook (ACS_LTEE); opchan.urhook (ACS_TTEE); opchan.lrhook (ACS_BTEE); //opchan.draw(); } void NCURSES_GUI::setdialogs (void) { } void NCURSES_GUI::changewin(int newwin) { int gc; gc = newwin * 2 + (activechan %2); if (gc != activechan) setactivechan (gc); } /* void NCURSES_GUI::stop() { warning ("muse_tui.stop()"); } */ void NCURSES_GUI::userinput () { float f; int ch; int quit=0; //char temp[50]; while (!quit) { wait(); ch = getch(); // warning ("getch() got %d", ch); if ((ch > 48) & (ch <= (48 + MAX_CHANNELS))) { setactivechan (ch - 49); } else switch (ch) { case KEY_TAB: tabchan(); break; case KEY_F1: // F1 case 80: // does keypad work? warning ("request change to win 1"); changewin (0); break; case KEY_F2: // F2 case 81: // does keypad work? warning ("request change to win 2"); changewin (1); break; case KEY_F3: // F3 case 82: // does keypad work? warning ("request change to win 3"); changewin (2); break; case KEY_UP: curs_chan[activechan].selprevitem(); break; case KEY_DOWN: curs_chan[activechan].selnextitem(); break; case '+': f = curs_chan[activechan].incrvol(); _mix->set_volume (activechan, f); break; case '-': f = curs_chan[activechan].decrvol(); _mix->set_volume (activechan, f); break; case '>': // fade right f = curs_chan[vischan[0]].decrvol(); _mix->set_volume (vischan[0], f); f = curs_chan[vischan[1]].incrvol(); _mix->set_volume (vischan[1], f); break; case '<': //fade left f = curs_chan[vischan[0]].incrvol(); _mix->set_volume (vischan[0], f); f = curs_chan[vischan[1]].decrvol(); _mix->set_volume (vischan[1], f); break; case 48: // 0 curs_chan[activechan].zerovol(); _mix->set_volume (activechan, 0); break; case 'u': case 'U': newurl(); refresh(); break; case 'f': case 'F': newfile(); refresh(); break; case 't': case 'T': /* talk */ break; case 'm': case 'M': _mix->set_playmode(activechan, curs_chan[activechan].cycmode()); break; case 'a': case 'A': //showabout(); refresh(); break; case 'k': case 'K': if (_mix->dspout==true) _mix->dspout=false; else _mix->dspout=true; /* speaker */ break; case 'l': case 'L': if (_mix->linein==true) _mix->linein=false; else _mix->linein=true; /* line-in */ break; case 'c': case 'C': setconnect(); /* FIXME adattare alla nuova api snprintf (temp, 49, "Muse - streaming http://%s:%u/%s",_mix->ice.ip,_mix->ice.port,_mix->ice.mount); if (_mix->ice.running) title.setvalueNR (temp); */ refresh(); /* connect */ break; case 'h': case 'H': /* connect */ showhelp(); refresh(); break; case 'r': /* for debugging purpose */ refresh(); break; case 'q': quit = 1; break; case 10: warning ("cplitem: %d", curs_chan[activechan].cplitem() + 1); _mix->set_channel (activechan, curs_chan[activechan].cplitem() + 1); _mix->play_channel (activechan); break; case 's': case 'S': _mix->stop_channel (activechan); break; default: continue; } warning ("quit = %d", quit); } /* si va a nanna */ /*FIXME nuova api if (_mix->ice.running) _mix->ice.stop(); */ _mix->quit = true; jsleep (0,200); } void NCURSES_GUI::setactivechan (int chanID, bool chkupd) { func ("NCURSES_GUI::setactivechan()"); warning ("activechan = %d", activechan); if (chkupd) canupdate = false; curs_chan[activechan].unsetctrl(); curs_chan[activechan].unreg(); if (activechan % 2 == 0) { curs_chan[activechan + 1].unreg(); } else { curs_chan[activechan - 1].unreg(); } activechan = chanID; curs_chan[activechan].setctrl(); curs_chan[activechan].reg(); curs_chan[activechan].show(); vischan[0] = activechan; if (activechan % 2 == 0) { curs_chan[activechan + 1].reg(); curs_chan[activechan + 1].show(); vischan[1] = activechan +1; } else { curs_chan[activechan - 1].reg(); curs_chan[activechan - 1].show(); vischan[1] = activechan -1; } if (vischan[0] > vischan[1]) { int temp; temp = vischan[0]; vischan[0] = vischan[1]; vischan[1] = temp; } snprintf (minibox, 15, "win: %d chan: %d", (activechan /2) +1, activechan + 1); opchan.setvalue(minibox); if (chkupd) canupdate = true; func ("end NCURSES_GUI::setactivechan()"); } void NCURSES_GUI::setactivechan (int chanID) { func ("NCURSES_GUI::setactivechan()"); warning ("activechan = %d", activechan); canupdate = false; curs_chan[activechan].unsetctrl(); curs_chan[activechan].unreg(); if (activechan % 2 == 0) { curs_chan[activechan + 1].unreg(); } else { curs_chan[activechan - 1].unreg(); } activechan = chanID; curs_chan[activechan].setctrl(); curs_chan[activechan].reg(); curs_chan[activechan].show(); vischan[0] = activechan; if (activechan % 2 == 0) { curs_chan[activechan + 1].reg(); curs_chan[activechan + 1].show(); vischan[1] = activechan +1; } else { curs_chan[activechan - 1].reg(); curs_chan[activechan - 1].show(); vischan[1] = activechan -1; } if (vischan[0] > vischan[1]) { int temp; temp = vischan[0]; vischan[0] = vischan[1]; vischan[1] = temp; } snprintf (minibox, 15, "win: %d chan: %d", (activechan /2) +1, activechan + 1); opchan.setvalue(minibox); canupdate = true; } int NCURSES_GUI::getactivechan (void) { return activechan; } void NCURSES_GUI::tabchan (void) { canupdate = false; if (activechan % 2 == 0) { setactivechan (activechan + 1); } else { setactivechan (activechan - 1); } canupdate = true; } void NCURSES_GUI::setconnect (void) { func ("NCURSES_GUI::setconnect()"); canupdate = false; //connbox.draw(); //connbox.refresh(); connbox->activate(); canupdate = true; func ("end NCURSES_GUI::setconnect()"); } void NCURSES_GUI::newurl (void) { char * url; CDKEntry urlentry; warning ("+url entry"); urlentry.setscreen (f.screen()); urlentry.setparm (NEWURLENTRY_TITLE, NEWURLENTRY_LABEL, 40, CENTER, CENTER); url = urlentry.activateonce(); if (url) { warning ("new url = %s", url); _mix->add_to_playlist (activechan, url); } } void NCURSES_GUI::newfile (void) { char *file; canupdate = false; CDKFselect fileselect; warning ("+file select"); fileselect.setscreen (f.screen()); fileselect.setbox(true); fileselect.setparm ( CENTER, CENTER, f.height()-8, f.width()-8, NEWFILESELECT_TITLE, NEWFILESELECT_LABEL ); file = fileselect.activateonce(); if (file) { warning ("new file = %s", file); _mix->add_to_playlist (activechan, file); } canupdate = true; } void NCURSES_GUI::showhelp (void) { CDKScroll help; char ** helpmsg; int count; count = 11; helpmsg = (char **) malloc (70*count); *(helpmsg + 0) = " DOWN - scroll down playlist"; *(helpmsg + 1) = " UP - scroll up playlist"; *(helpmsg + 2) = " F1 - flip over win 1"; *(helpmsg + 3) = " F2 - flip over win 2"; *(helpmsg + 4) = " F3 - flip over win 3"; *(helpmsg + 5) = " 1-6 - goto chan (automagically change win)"; *(helpmsg + 6) = " TAB - switch between chan on the same win"; *(helpmsg + 7) = " "; *(helpmsg + 8) = " ENTER - play [+-] - volume "; *(helpmsg + 9) = " s - stop [<>] - fade "; *(helpmsg + 10) =" m - play mode 0 - set volume to 0 "; help.setscreen (f.screen()); help.setparm (0, 5, 5, f.height()-10, f.width()-10, helpmsg, count, 0, A_NORMAL); canupdate = false; help.draw(); help.waitkey(); help.destroy(); canupdate = true; free (helpmsg); } void NCURSES_GUI::showabout (void) { aboutbox about; about.setscreen (f.screen()); about.setitem(); about.setparm (0, CENTER, CENTER, f.height()-10, 80, 0, A_NORMAL); canupdate = false; about.draw(); about.activate(); about.destroy(); canupdate = true; } void NCURSES_GUI::set_lcd (unsigned int chan, char *lcd) { //if(ch_lcd[chan]) free(ch_lcd[chan]); //ch_lcd[chan] = strdup(lcd); if (canupdate) { if ((vischan[0] == chan) | (vischan[1] == chan)) curs_chan[chan].set_time (lcd); } } void NCURSES_GUI::set_pos(unsigned int chan, float pos) { ch_pos[chan] = pos; if (canupdate) { if ((vischan[0] == chan) | (vischan[1] == chan)) curs_chan[chan].set_pos (pos); } } void NCURSES_GUI::set_title(char *txt) { func ("NCURSES_GUI::set_title()"); if (canupdate) { title.setvalue (txt); } else { title.setvalueNR (txt); } } void NCURSES_GUI::set_status(char *txt) { if (canupdate) { statusbar.setvalue (txt); } else { statusbar.setvalueNR (txt); } } void NCURSES_GUI::add_playlist(unsigned int ch, char *txt) { curs_chan[ch].add_to_playlist (txt); } void NCURSES_GUI::sel_playlist(unsigned int ch, int row) { }