File indexing completed on 2024-04-28 08:46:22
0001 /* 0002 This file is part of the KMPlayer application 0003 SPDX-FileCopyrightText: 2004 Koos Vriezen <koos.vriezen@xs4all.nl> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include <cmath> 0009 #include <unistd.h> 0010 0011 #include <QLayout> 0012 #include <QLabel> 0013 #include <QMap> 0014 #include <QTimer> 0015 #include <QPushButton> 0016 #include <Q3ButtonGroup> 0017 #include <QCheckBox> 0018 #include <QTable> 0019 #include <QStringList> 0020 #include <QComboBox> 0021 #include <QLineEdit> 0022 #include <QGroupBox> 0023 #include <QWhatsThis> 0024 #include <QTabWidget> 0025 #include <QRadioButton> 0026 #include <QMessageBox> 0027 #include <QSocket> 0028 #include <QEventLoop> 0029 0030 #include <KLocalizedString> 0031 #include <KMessageBox> 0032 #include <KLineEdit> 0033 #include <KUrlRequester> 0034 #include <KComboBox> 0035 #include <kstatusbar.h> 0036 #include <kprocess.h> 0037 #include <KConfig> 0038 #include <kaction.h> 0039 #include <KIconLoader> 0040 #include <klistview.h> 0041 #include <kinputdialog.h> 0042 0043 #include "kmplayerapp_log.h" 0044 #include "kmplayer_backend_stub.h" 0045 #include "kmplayer_callback.h" 0046 #include "kmplayerpartbase.h" 0047 #include "kmplayercontrolpanel.h" 0048 #include "kmplayerconfig.h" 0049 #include "playlistview.h" 0050 #include "viewarea.h" 0051 #include "kmplayervdr.h" 0052 #include "kmplayer.h" 0053 0054 using namespace KMPlayer; 0055 0056 static const char * strVDR = "VDR"; 0057 static const char * strVDRPort = "Port"; 0058 static const char * strXVPort = "XV Port"; 0059 static const char * strXVEncoding = "XV Encoding"; 0060 static const char * strXVScale = "XV Scale"; 0061 0062 KMPlayerPrefSourcePageVDR::KMPlayerPrefSourcePageVDR (QWidget * parent, KMPlayer::PartBase * player) 0063 : QFrame (parent), m_player (player) { 0064 //KUrlRequester * v4ldevice; 0065 QVBoxLayout *layout = new QVBoxLayout (this, 5, 2); 0066 QGridLayout *gridlayout = new QGridLayout (1, 2); 0067 xv_port = new KListView (this); 0068 xv_port->addColumn (QString()); 0069 xv_port->header()->hide (); 0070 xv_port->setTreeStepSize (15); 0071 //xv_port->setRootIsDecorated (true); 0072 //xv_port->setSorting (-1); 0073 Q3ListViewItem * vitem = new Q3ListViewItem (xv_port, i18n ("XVideo port")); 0074 vitem->setOpen (true); 0075 QWhatsThis::add (xv_port, i18n ("Port base of the X Video extension.\nIf left to default (0), the first available port will be used. However if you have multiple XVideo instances, you might have to provide the port to use here.\nSee the output from 'xvinfo' for more information")); 0076 QLabel * label = new QLabel (i18n ("Communication port:"), this); 0077 gridlayout->addWidget (label, 0, 0); 0078 tcp_port = new QLineEdit ("", this); 0079 QWhatsThis::add (tcp_port, i18n ("Communication port with VDR. Default is port 2001.\nIf you use another port, with the '-p' option of 'vdr', you must set it here too.")); 0080 gridlayout->addWidget (tcp_port, 0, 1); 0081 layout->addWidget (xv_port); 0082 layout->addLayout (gridlayout); 0083 scale = new Q3ButtonGroup (2, Qt::Vertical, i18n ("Scale"), this); 0084 new QRadioButton (i18n ("4:3"), scale); 0085 new QRadioButton (i18n ("16:9"), scale); 0086 QWhatsThis::add (scale, i18n ("Aspects to use when viewing VDR")); 0087 scale->setButton (0); 0088 layout->addWidget (scale); 0089 layout->addItem (new QSpacerItem (5, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); 0090 } 0091 0092 KMPlayerPrefSourcePageVDR::~KMPlayerPrefSourcePageVDR () {} 0093 0094 void KMPlayerPrefSourcePageVDR::showEvent (QShowEvent *) { 0095 XvProcessInfo *pi = static_cast<XvProcessInfo *>(m_player->mediaManager()-> 0096 processInfos()["xvideo"]); 0097 if (!pi->config_doc) 0098 pi->getConfigData (); 0099 } 0100 //----------------------------------------------------------------------------- 0101 0102 static const char * cmd_chan_query = "CHAN\n"; 0103 static const char * cmd_list_channels = "LSTC\n"; 0104 static const char * cmd_volume_query = "VOLU\n"; 0105 0106 class VDRCommand { 0107 public: 0108 VDRCommand (const char * c, VDRCommand * n=0L) 0109 : command (strdup (c)), next (n) {} 0110 ~VDRCommand () { free (command); } 0111 char * command; 0112 VDRCommand * next; 0113 }; 0114 0115 //----------------------------------------------------------------------------- 0116 0117 KMPlayerVDRSource::KMPlayerVDRSource (KMPlayerApp * app) 0118 : KMPlayer::Source (QString ("VDR"), app->player (), "vdrsource"), 0119 m_app (app), 0120 m_configpage (0), 0121 m_socket (new QSocket (this)), 0122 commands (0L), 0123 channel_timer (0), 0124 timeout_timer (0), 0125 finish_timer (0), 0126 tcp_port (0), 0127 m_stored_volume (0) { 0128 memset (m_actions, 0, sizeof (KAction *) * int (act_last)); 0129 m_player->settings ()->addPage (this); 0130 connect (m_socket, SIGNAL (connectionClosed()), this, SLOT(disconnected())); 0131 connect (m_socket, SIGNAL (connected ()), this, SLOT (connected ())); 0132 connect (m_socket, SIGNAL (readyRead ()), this, SLOT (readyRead ())); 0133 connect (m_socket, SIGNAL (error (int)), this, SLOT (socketError (int))); 0134 } 0135 0136 KMPlayerVDRSource::~KMPlayerVDRSource () {} 0137 0138 void KMPlayerVDRSource::waitForConnectionClose () { 0139 if (timeout_timer) { 0140 finish_timer = startTimer (500); 0141 kdDebug () << "VDR connection not yet closed" << endl; 0142 QApplication::eventLoop ()->enterLoop (); 0143 kdDebug () << "VDR connection:" << (m_socket->state () == QSocket::Connected) << endl; 0144 timeout_timer = 0; 0145 } 0146 } 0147 0148 bool KMPlayerVDRSource::hasLength () { 0149 return false; 0150 } 0151 0152 bool KMPlayerVDRSource::isSeekable () { 0153 return true; 0154 } 0155 0156 QString KMPlayerVDRSource::prettyName () { 0157 return i18n ("VDR"); 0158 } 0159 0160 void KMPlayerVDRSource::activate () { 0161 last_channel = 0; 0162 connect (this, SIGNAL (startPlaying ()), this, SLOT (processStarted())); 0163 connect (this, SIGNAL (stopPlaying ()), this, SLOT (processStopped ())); 0164 KMPlayer::ControlPanel * panel = m_app->view()->controlPanel (); 0165 panel->button (KMPlayer::ControlPanel::button_red)->show (); 0166 panel->button (KMPlayer::ControlPanel::button_green)->show (); 0167 panel->button (KMPlayer::ControlPanel::button_yellow)->show (); 0168 panel->button (KMPlayer::ControlPanel::button_blue)->show (); 0169 panel->button (KMPlayer::ControlPanel::button_pause)->hide (); 0170 panel->button (KMPlayer::ControlPanel::button_record)->hide (); 0171 connect (panel->volumeBar (), SIGNAL (volumeChanged (int)), this, SLOT (volumeChanged (int))); 0172 connect (panel->button (KMPlayer::ControlPanel::button_red), SIGNAL (clicked ()), this, SLOT (keyRed ())); 0173 connect (panel->button (KMPlayer::ControlPanel::button_green), SIGNAL (clicked ()), this, SLOT (keyGreen ())); 0174 connect (panel->button (KMPlayer::ControlPanel::button_yellow), SIGNAL (clicked ()), this, SLOT (keyYellow ())); 0175 connect (panel->button (KMPlayer::ControlPanel::button_blue), SIGNAL (clicked ()), this, SLOT (keyBlue ())); 0176 setAspect (m_document, scale ? 16.0/9 : 1.33); 0177 if (!m_url.scheme().compare ("kmplayer")) 0178 m_request_jump = QUrl::fromPercentEncoding(m_url.path().latin1()).mid (1); 0179 setUrl (QString ("vdr://localhost:%1").arg (tcp_port)); 0180 QTimer::singleShot (0, m_player, SLOT (play ())); 0181 } 0182 0183 void KMPlayerVDRSource::deactivate () { 0184 disconnect (m_socket, SIGNAL (error (int)), this, SLOT (socketError (int))); 0185 if (m_player->view ()) { 0186 disconnect (this, SIGNAL(startPlaying()), this, SLOT(processStarted())); 0187 disconnect (this, SIGNAL (stopPlaying()), this, SLOT(processStopped())); 0188 KMPlayer::ControlPanel * panel = m_app->view()->controlPanel (); 0189 disconnect (panel->volumeBar (), SIGNAL (volumeChanged (int)), this, SLOT (volumeChanged (int))); 0190 disconnect (panel->button (KMPlayer::ControlPanel::button_red), SIGNAL (clicked ()), this, SLOT (keyRed ())); 0191 disconnect (panel->button (KMPlayer::ControlPanel::button_green), SIGNAL (clicked ()), this, SLOT (keyGreen ())); 0192 disconnect (panel->button (KMPlayer::ControlPanel::button_yellow), SIGNAL (clicked ()), this, SLOT (keyYellow ())); 0193 disconnect (panel->button (KMPlayer::ControlPanel::button_blue), SIGNAL (clicked ()), this, SLOT (keyBlue ())); 0194 } 0195 processStopped (); 0196 m_request_jump.truncate (0); 0197 } 0198 0199 void KMPlayerVDRSource::processStopped () { 0200 if (m_socket->state () == QSocket::Connected) { 0201 queueCommand (QString ("VOLU %1\n").arg (m_stored_volume).ascii ()); 0202 queueCommand ("QUIT\n"); 0203 } 0204 } 0205 0206 void KMPlayerVDRSource::processStarted () { 0207 m_socket->connectToHost ("127.0.0.1", tcp_port); 0208 commands = new VDRCommand ("connect", commands); 0209 } 0210 0211 #define DEF_ACT(i,text,pix,scut,slot,name) \ 0212 m_actions [i] = new KAction (text, QString (pix), KShortcut (scut), this, slot, m_app->actionCollection (), name); \ 0213 m_fullscreen_actions [i] = new KAction (text, KShortcut (scut), this, slot, m_app->view ()->viewArea ()->actionCollection (), name) 0214 0215 void KMPlayerVDRSource::connected () { 0216 queueCommand (cmd_list_channels); 0217 queueCommand (cmd_volume_query); 0218 killTimer (channel_timer); 0219 channel_timer = startTimer (3000); 0220 KAction * action = m_app->actionCollection ()->action ("vdr_connect"); 0221 action->setIcon (QString ("network-disconnect")); 0222 action->setText (i18n ("Dis&connect")); 0223 DEF_ACT (act_up, i18n ("VDR Key Up"), "go-up", , SLOT (keyUp ()), "vdr_key_up"); 0224 DEF_ACT (act_down, i18n ("VDR Key Down"), "go-down", , SLOT (keyDown ()), "vdr_key_down"); 0225 DEF_ACT (act_back, i18n ("VDR Key Back"), "go-previous", , SLOT (keyBack ()), "vdr_key_back"); 0226 DEF_ACT (act_ok, i18n ("VDR Key Ok"), "dialog-ok", , SLOT (keyOk ()), "vdr_key_ok"); 0227 DEF_ACT (act_setup, i18n ("VDR Key Setup"), "configure", , SLOT (keySetup ()), "vdr_key_setup"); 0228 DEF_ACT (act_channels, i18n ("VDR Key Channels"), "view-media-playlist", , SLOT (keyChannels ()), "vdr_key_channels"); 0229 DEF_ACT (act_menu, i18n ("VDR Key Menu"), "show-menu", , SLOT (keyMenu ()), "vdr_key_menu"); 0230 DEF_ACT (act_red, i18n ("VDR Key Red"), "red", , SLOT (keyRed ()), "vdr_key_red"); 0231 DEF_ACT (act_green, i18n ("VDR Key Green"), "green", , SLOT (keyGreen ()), "vdr_key_green"); 0232 DEF_ACT (act_yellow, i18n ("VDR Key Yellow"), "yellow", , SLOT (keyYellow ()), "vdr_key_yellow"); 0233 DEF_ACT (act_blue, i18n ("VDR Key Blue"), "blue", , SLOT (keyBlue ()), "vdr_key_blue"); 0234 DEF_ACT (act_custom, "VDR Custom Command", "system-run", , SLOT (customCmd ()), "vdr_key_custom"); 0235 m_app->initMenu (); // update menu and toolbar 0236 DEF_ACT (act_0, i18n ("VDR Key 0"), "0", Qt::Key_0, SLOT (key0 ()), "vdr_key_0"); 0237 DEF_ACT (act_1, i18n ("VDR Key 1"), "1", Qt::Key_1, SLOT (key1 ()), "vdr_key_1"); 0238 DEF_ACT (act_2, i18n ("VDR Key 2"), "2", Qt::Key_2, SLOT (key2 ()), "vdr_key_2"); 0239 DEF_ACT (act_3, i18n ("VDR Key 3"), "3", Qt::Key_3, SLOT (key3 ()), "vdr_key_3"); 0240 DEF_ACT (act_4, i18n ("VDR Key 4"), "4", Qt::Key_4, SLOT (key4 ()), "vdr_key_4"); 0241 DEF_ACT (act_5, i18n ("VDR Key 5"), "5", Qt::Key_5, SLOT (key5 ()), "vdr_key_5"); 0242 DEF_ACT (act_6, i18n ("VDR Key 6"), "6", Qt::Key_6, SLOT (key6 ()), "vdr_key_6"); 0243 DEF_ACT (act_7, i18n ("VDR Key 7"), "7", Qt::Key_7, SLOT (key7 ()), "vdr_key_7"); 0244 DEF_ACT (act_8, i18n ("VDR Key 8"), "8", Qt::Key_8, SLOT (key8 ()), "vdr_key_8"); 0245 DEF_ACT (act_9, i18n ("VDR Key 9"), "9", Qt::Key_9, SLOT (key9 ()), "vdr_key_9"); 0246 //KMPlayer::ViewLayer * layer = m_app->view ()->viewArea (); 0247 for (int i = 0; i < int (act_last); ++i) 0248 // somehow, the configured shortcuts only show up after createGUI() call 0249 m_fullscreen_actions [i]->setShortcut (m_actions [i]->shortcut ()); 0250 // m_fullscreen_actions[i]->plug (layer); 0251 } 0252 0253 #undef DEF_ACT 0254 0255 void KMPlayerVDRSource::disconnected () { 0256 kdDebug() << "disconnected " << commands << endl; 0257 if (finish_timer) { 0258 deleteCommands (); 0259 return; 0260 } 0261 setUrl (QString ("vdr://localhost:%1").arg (tcp_port)); 0262 if (channel_timer && m_player->source () == this) 0263 m_player->stop (); 0264 deleteCommands (); 0265 KAction * action = m_app->actionCollection ()->action ("vdr_connect"); 0266 action->setIcon (QString ("network-connect")); 0267 action->setText (i18n ("&Connect")); 0268 m_app->guiFactory ()->removeClient (m_app);// crash w/ m_actions[i]->unplugAll (); in for loop below 0269 for (int i = 0; i < int (act_last); ++i) 0270 if (m_player->view () && m_actions[i]) { 0271 m_fullscreen_actions[i]->unplug (m_app->view()->viewArea()); 0272 delete m_actions[i]; 0273 delete m_fullscreen_actions[i]; 0274 } 0275 m_app->initMenu (); 0276 } 0277 0278 void KMPlayerVDRSource::toggleConnected () { 0279 if (m_socket->state () == QSocket::Connected) { 0280 queueCommand ("QUIT\n"); 0281 killTimer (channel_timer); 0282 channel_timer = 0; 0283 } else { 0284 m_socket->connectToHost ("127.0.0.1", tcp_port); 0285 commands = new VDRCommand ("connect", commands); 0286 } 0287 } 0288 0289 void KMPlayerVDRSource::volumeChanged (int val) { 0290 queueCommand (QString ("VOLU %1\n").arg (int (sqrt (255 * 255 * val / 100))).ascii ()); 0291 } 0292 0293 static struct ReadBuf { 0294 char * buf; 0295 int length; 0296 ReadBuf () : buf (0L), length (0) {} 0297 ~ReadBuf () { 0298 clear (); 0299 } 0300 void operator += (const char * s) { 0301 int l = strlen (s); 0302 char * b = new char [length + l + 1]; 0303 if (length) 0304 strcpy (b, buf); 0305 strcpy (b + length, s); 0306 length += l; 0307 delete buf; 0308 buf = b; 0309 } 0310 QCString mid (int p) { 0311 return QCString (buf + p); 0312 } 0313 QCString left (int p) { 0314 return QCString (buf, p); 0315 } 0316 QCString getReadLine (); 0317 void clear () { 0318 delete [] buf; 0319 buf = 0; 0320 length = 0; 0321 } 0322 } readbuf; 0323 0324 QCString ReadBuf::getReadLine () { 0325 QCString out; 0326 if (!length) 0327 return out; 0328 int p = strcspn (buf, "\r\n"); 0329 if (p < length) { 0330 int skip = strspn (buf + p, "\r\n"); 0331 out = left (p+1); 0332 int nl = length - p - skip; 0333 memmove (buf, buf + p + skip, nl + 1); 0334 length = nl; 0335 } 0336 return out; 0337 } 0338 0339 void KMPlayerVDRSource::readyRead () { 0340 KMPlayer::View * v = finish_timer ? 0L : static_cast <KMPlayer::View *> (m_player->view ()); 0341 long nr = m_socket->bytesAvailable(); 0342 char * data = new char [nr + 1]; 0343 m_socket->readBlock (data, nr); 0344 data [nr] = 0; 0345 readbuf += data; 0346 QCString line = readbuf.getReadLine (); 0347 if (commands) { 0348 bool cmd_done = false; 0349 while (!line.isEmpty ()) { 0350 bool toconsole = true; 0351 cmd_done = (line.length () > 3 && line[3] == ' '); // from svdrpsend.pl 0352 // kdDebug () << "readyRead " << cmd_done << " " << commands->command << endl; 0353 if (!strcmp (commands->command, cmd_list_channels) && m_document) { 0354 int p = line.find (';'); 0355 int q = line.find (':'); 0356 if (q > 0 && (p < 0 || q < p)) 0357 p = q; 0358 if (p > 0) 0359 line.truncate (p); 0360 QString channel_name = line.mid (4); 0361 m_document->appendChild (new KMPlayer::GenericMrl (m_document, QString ("kmplayer://vdrsource/%1").arg(channel_name), channel_name)); 0362 if (cmd_done) { 0363 m_player->updateTree (); 0364 if (!m_request_jump.isEmpty ()) { 0365 jump (m_request_jump); 0366 m_request_jump.truncate (0); 0367 } 0368 } 0369 toconsole = false; 0370 } else if (!strcmp (commands->command, cmd_chan_query)) { 0371 if (v && line.length () > 4) { 0372 QString ch = line.mid (4); 0373 setTitle (ch); 0374 KMPlayer::PlayListItem * lvi = static_cast <KMPlayer::PlayListItem *> (v->playList ()->findItem (ch, 0)); 0375 if (lvi && lvi->node != m_last_channel) { 0376 KMPlayer::PlayListItem * si = static_cast <KMPlayer::PlayListItem *> (v->playList ()->selectedItem ()); 0377 bool jump_selection = (si && (si->node == m_document || si->node == m_last_channel)); 0378 if (m_last_channel) 0379 m_last_channel->setState (KMPlayer::Node::state_finished); 0380 m_last_channel = lvi->node; 0381 if (m_last_channel) 0382 m_last_channel->setState (KMPlayer::Node::state_began); 0383 if (jump_selection) { 0384 v->playList ()->setSelected (lvi, true); 0385 v->playList ()->ensureItemVisible (lvi); 0386 } 0387 v->playList ()->triggerUpdate (); 0388 } 0389 //v->playList ()->selectItem (ch); 0390 int c = strtol(ch.ascii(), 0L, 10); 0391 if (c != last_channel) { 0392 last_channel = c; 0393 m_app->statusBar ()->changeItem (QString::number (c), 0394 id_status_timer); 0395 } 0396 } 0397 } else if (cmd_done && !strcmp(commands->command,cmd_volume_query)){ 0398 int pos = line.lastIndexOf (QChar (' ')); 0399 if (pos > 0) { 0400 QString vol = line.mid (pos + 1); 0401 if (!vol.compare ("mute")) 0402 m_stored_volume = 0; 0403 else 0404 m_stored_volume = vol.toInt (); 0405 if (m_stored_volume == 0) 0406 volumeChanged (m_app->view ()->controlPanel ()->volumeBar ()->value ()); 0407 } 0408 } 0409 if (v && toconsole) 0410 v->addText (QString (line), true); 0411 line = readbuf.getReadLine (); 0412 } 0413 if (cmd_done) { 0414 VDRCommand * c = commands->next; 0415 delete commands; 0416 commands = c; 0417 if (commands) 0418 sendCommand (); 0419 else { 0420 killTimer (timeout_timer); 0421 timeout_timer = 0; 0422 } 0423 } 0424 } 0425 delete [] data; 0426 } 0427 0428 void KMPlayerVDRSource::socketError (int code) { 0429 if (code == QSocket::ErrHostNotFound) { 0430 KMessageBox::error (m_configpage, i18n ("Host not found"), i18n ("Error")); 0431 } else if (code == QSocket::ErrConnectionRefused) { 0432 KMessageBox::error (m_configpage, i18n ("Connection refused"), i18n ("Error")); 0433 } 0434 } 0435 0436 void KMPlayerVDRSource::queueCommand (const char * cmd) { 0437 if (m_player->source () != this) 0438 return; 0439 if (!commands) { 0440 readbuf.clear (); 0441 commands = new VDRCommand (cmd); 0442 if (m_socket->state () == QSocket::Connected) { 0443 sendCommand (); 0444 } else { 0445 m_socket->connectToHost ("127.0.0.1", tcp_port); 0446 commands = new VDRCommand ("connect", commands); 0447 } 0448 } else { 0449 VDRCommand * c = commands; 0450 for (int i = 0; i < 10; ++i, c = c->next) 0451 if (!c->next) { 0452 c->next = new VDRCommand (cmd); 0453 break; 0454 } 0455 } 0456 } 0457 0458 void KMPlayerVDRSource::queueCommand (const char * cmd, int t) { 0459 queueCommand (cmd); 0460 killTimer (channel_timer); 0461 channel_timer = startTimer (t); 0462 } 0463 0464 void KMPlayerVDRSource::sendCommand () { 0465 //kdDebug () << "sendCommand " << commands->command << endl; 0466 m_socket->writeBlock (commands->command, strlen(commands->command)); 0467 m_socket->flush (); 0468 killTimer (timeout_timer); 0469 timeout_timer = startTimer (30000); 0470 } 0471 0472 void KMPlayerVDRSource::customCmd () { 0473 QString cmd = KInputDialog::getText (i18n ("Custom VDR command"), i18n ("You can pass commands to VDR.\nEnter 'HELP' to see a list of available commands.\nYou can see VDR response in the console window.\n\nVDR Command:"), QString(), 0, m_player->view ()); 0474 if (!cmd.isEmpty ()) 0475 queueCommand (QString (cmd + QChar ('\n')).local8Bit ()); 0476 } 0477 0478 void KMPlayerVDRSource::timerEvent (QTimerEvent * e) { 0479 if (e->timerId () == timeout_timer || e->timerId () == finish_timer) { 0480 deleteCommands (); 0481 } else if (e->timerId () == channel_timer) { 0482 queueCommand (cmd_chan_query); 0483 killTimer (channel_timer); 0484 channel_timer = startTimer (30000); 0485 } 0486 } 0487 0488 void KMPlayerVDRSource::deleteCommands () { 0489 killTimer (timeout_timer); 0490 timeout_timer = 0; 0491 killTimer (channel_timer); 0492 channel_timer = 0; 0493 for (VDRCommand * c = commands; c; c = commands) { 0494 commands = commands->next; 0495 delete c; 0496 } 0497 readbuf.clear (); 0498 if (finish_timer) { 0499 killTimer (finish_timer); 0500 QApplication::eventLoop ()->exitLoop (); 0501 } 0502 } 0503 0504 void KMPlayerVDRSource::play (KMPlayer::Mrl *mrl) { 0505 if (!mrl || !mrl->isPlayable ()) return; 0506 jump (mrl->pretty_name); 0507 } 0508 0509 void KMPlayerVDRSource::jump (const QString & channel) { 0510 QCString c ("CHAN "); 0511 QCString ch = channel.local8Bit (); 0512 int p = ch.find (' '); 0513 if (p > 0) 0514 c += ch.left (p); 0515 else 0516 c += ch; // hope for the best .. 0517 c += '\n'; 0518 queueCommand (c); 0519 } 0520 0521 void KMPlayerVDRSource::forward () { 0522 queueCommand ("CHAN +\n", 1000); 0523 } 0524 0525 void KMPlayerVDRSource::backward () { 0526 queueCommand ("CHAN -\n", 1000); 0527 } 0528 0529 void KMPlayerVDRSource::keyUp () { 0530 queueCommand ("HITK UP\n", 1000); 0531 } 0532 0533 void KMPlayerVDRSource::keyDown () { 0534 queueCommand ("HITK DOWN\n", 1000); 0535 } 0536 0537 void KMPlayerVDRSource::keyBack () { 0538 queueCommand ("HITK BACK\n"); 0539 } 0540 0541 void KMPlayerVDRSource::keyOk () { 0542 queueCommand ("HITK OK\n"); 0543 } 0544 0545 void KMPlayerVDRSource::keySetup () { 0546 queueCommand ("HITK SETUP\n"); 0547 } 0548 0549 void KMPlayerVDRSource::keyChannels () { 0550 queueCommand ("HITK CHANNELS\n"); 0551 } 0552 0553 void KMPlayerVDRSource::keyMenu () { 0554 queueCommand ("HITK MENU\n"); 0555 } 0556 0557 void KMPlayerVDRSource::key0 () { 0558 queueCommand ("HITK 0\n", 2000); 0559 } 0560 0561 void KMPlayerVDRSource::key1 () { 0562 queueCommand ("HITK 1\n", 2000); 0563 } 0564 0565 void KMPlayerVDRSource::key2 () { 0566 queueCommand ("HITK 2\n", 2000); 0567 } 0568 0569 void KMPlayerVDRSource::key3 () { 0570 queueCommand ("HITK 3\n", 2000); 0571 } 0572 0573 void KMPlayerVDRSource::key4 () { 0574 queueCommand ("HITK 4\n", 2000); 0575 } 0576 0577 void KMPlayerVDRSource::key5 () { 0578 queueCommand ("HITK 5\n", 2000); 0579 } 0580 0581 void KMPlayerVDRSource::key6 () { 0582 queueCommand ("HITK 6\n", 2000); 0583 } 0584 0585 void KMPlayerVDRSource::key7 () { 0586 queueCommand ("HITK 7\n", 2000); 0587 } 0588 0589 void KMPlayerVDRSource::key8 () { 0590 queueCommand ("HITK 8\n", 2000); 0591 } 0592 0593 void KMPlayerVDRSource::key9 () { 0594 queueCommand ("HITK 9\n", 2000); 0595 } 0596 0597 void KMPlayerVDRSource::keyRed () { 0598 queueCommand ("HITK RED\n"); 0599 } 0600 0601 void KMPlayerVDRSource::keyGreen () { 0602 queueCommand ("HITK GREEN\n"); 0603 } 0604 0605 void KMPlayerVDRSource::keyYellow () { 0606 queueCommand ("HITK YELLOW\n"); 0607 } 0608 0609 void KMPlayerVDRSource::keyBlue () { 0610 queueCommand ("HITK BLUE\n"); 0611 } 0612 0613 void KMPlayerVDRSource::write (KConfig * m_config) { 0614 m_config->setGroup (strVDR); 0615 m_config->writeEntry (strVDRPort, tcp_port); 0616 m_config->writeEntry (strXVPort, m_xvport); 0617 m_config->writeEntry (strXVEncoding, m_xvencoding); 0618 m_config->writeEntry (strXVScale, scale); 0619 } 0620 0621 void KMPlayerVDRSource::read (KConfig * m_config) { 0622 m_config->setGroup (strVDR); 0623 tcp_port = m_config->readNumEntry (strVDRPort, 2001); 0624 m_xvport = m_config->readNumEntry (strXVPort, 0); 0625 m_xvencoding = m_config->readNumEntry (strXVEncoding, 0); 0626 scale = m_config->readNumEntry (strXVScale, 0); 0627 } 0628 0629 struct XVTreeItem : public Q3ListViewItem { 0630 XVTreeItem (Q3ListViewItem *parent, const QString & t, int p, int e) 0631 : Q3ListViewItem (parent, t), port (p), encoding (e) {} 0632 int port; 0633 int encoding; 0634 }; 0635 0636 void KMPlayerVDRSource::sync (bool fromUI) { 0637 XvProcessInfo *pi = static_cast<XvProcessInfo *>(m_player->mediaManager()-> 0638 processInfos()["xvideo"]); 0639 if (fromUI) { 0640 tcp_port = m_configpage->tcp_port->text ().toInt (); 0641 scale = m_configpage->scale->id (m_configpage->scale->selected ()); 0642 setAspect (m_document, scale ? 16.0/9 : 1.25); 0643 XVTreeItem * vitem = dynamic_cast <XVTreeItem *> (m_configpage->xv_port->selectedItem ()); 0644 if (vitem) { 0645 m_xvport = vitem->port; 0646 m_xvencoding = vitem->encoding; 0647 } 0648 } else { 0649 m_configpage->tcp_port->setText (QString::number (tcp_port)); 0650 m_configpage->scale->setButton (scale); 0651 Q3ListViewItem * vitem = m_configpage->xv_port->firstChild (); 0652 NodePtr configdoc = pi->config_doc; 0653 if (configdoc && configdoc->firstChild ()) { 0654 for (Q3ListViewItem *i=vitem->firstChild(); i; i=vitem->firstChild()) 0655 delete i; 0656 NodePtr node = configdoc->firstChild (); 0657 for (node = node->firstChild (); node; node = node->nextSibling()) { 0658 if (!node->isElementNode ()) 0659 continue; // some text sneaked in ? 0660 Element * elm = convertNode <Element> (node); 0661 if (elm->getAttribute (KMPlayer::StringPool::attr_type) != 0662 QString ("tree")) 0663 continue; 0664 for (NodePtr n = elm->firstChild (); n; n = n->nextSibling ()) { 0665 if (!n->isElementNode () || strcmp (n->nodeName (), "Port")) 0666 continue; 0667 Element * e = convertNode <Element> (n); 0668 QString portatt = e->getAttribute ( 0669 KMPlayer::StringPool::attr_value); 0670 int port; 0671 Q3ListViewItem *pi = new Q3ListViewItem (vitem, i18n ("Port ") + portatt); 0672 port = portatt.toInt (); 0673 for (NodePtr in=e->firstChild(); in; in=in->nextSibling()) { 0674 if (!in->isElementNode () || 0675 strcmp (in->nodeName (), "Input")) 0676 continue; 0677 Element * i = convertNode <Element> (in); 0678 QString inp = i->getAttribute ( 0679 KMPlayer::StringPool::attr_name); 0680 int enc = i->getAttribute ( 0681 KMPlayer::StringPool::attr_value).toInt (); 0682 Q3ListViewItem * ii = new XVTreeItem(pi, inp, port, enc); 0683 if (m_xvport == port && enc == m_xvencoding) { 0684 ii->setSelected (true); 0685 m_configpage->xv_port->ensureItemVisible (ii); 0686 } 0687 } 0688 } 0689 } 0690 } else { // wait for showEvent 0691 connect(pi, SIGNAL(configReceived()), this, SLOT(configReceived())); 0692 } 0693 } 0694 } 0695 0696 void KMPlayerVDRSource::configReceived () { 0697 XvProcessInfo *pi = static_cast<XvProcessInfo *>(m_player->mediaManager()-> 0698 processInfos()["xvideo"]); 0699 disconnect (pi, SIGNAL (configReceived()), this, SLOT (configReceived())); 0700 sync (false); 0701 } 0702 0703 void KMPlayerVDRSource::prefLocation (QString & item, QString & icon, QString & tab) { 0704 item = i18n ("Source"); 0705 icon = QString ("source"); 0706 tab = i18n ("VDR"); 0707 } 0708 0709 QFrame * KMPlayerVDRSource::prefPage (QWidget * parent) { 0710 if (!m_configpage) 0711 m_configpage = new KMPlayerPrefSourcePageVDR (parent, m_player); 0712 return m_configpage; 0713 } 0714 0715 void KMPlayerVDRSource::stateElementChanged (KMPlayer::Node *, KMPlayer::Node::State, KMPlayer::Node::State) { 0716 } 0717 0718 //----------------------------------------------------------------------------- 0719 0720 static const char * xv_supported [] = { 0721 "tvsource", "vdrsource", 0L 0722 }; 0723 0724 XvProcessInfo::XvProcessInfo (MediaManager *mgr) 0725 : CallbackProcessInfo ("xvideo", i18n ("X&Video"), xv_supported, mgr, NULL) {} 0726 0727 IProcess *XvProcessInfo::create (PartBase *part, AudioVideoMedia *media) { 0728 XVideo *x = new XVideo (part, this, part->settings ()); 0729 x->setSource (part->source ()); 0730 x->media_object = media; 0731 part->processCreated (x); 0732 return x; 0733 } 0734 0735 bool XvProcessInfo::startBackend () { 0736 if (m_process && m_process->isRunning ()) 0737 return true; 0738 Settings *cfg = manager->player ()->settings(); 0739 0740 initProcess (); 0741 0742 QString cmd = QString ("kxvplayer -cb %1").arg (dcopName ()); 0743 if (have_config == config_unknown || have_config == config_probe) 0744 cmd += QString (" -c"); 0745 //if (m_source) { 0746 // int xv_port = m_source->xvPort (); 0747 // int xv_encoding = m_source->xvEncoding (); 0748 // int freq = m_source->frequency (); 0749 // cmd += QString (" -port %1 -enc %2 -norm \"%3\"").arg (xv_port).arg (xv_encoding).arg (m_source->videoNorm ()); 0750 // if (freq > 0) 0751 // cmd += QString (" -freq %1").arg (freq); 0752 //} 0753 fprintf (stderr, "%s\n", cmd.latin1 ()); 0754 *m_process << cmd; 0755 m_process->start (KProcess::NotifyOnExit, KProcess::All); 0756 0757 return m_process->isRunning (); 0758 } 0759 0760 XVideo::XVideo (QObject *p, ProcessInfo *pi, Settings *s) 0761 : KMPlayer::CallbackProcess (p, pi, s, "xvideo") { 0762 //m_player->settings ()->addPage (m_configpage); 0763 } 0764 0765 XVideo::~XVideo () {} 0766 0767 bool XVideo::ready () { 0768 if (running () || !media_object || !media_object->viewer) { 0769 setState (IProcess::Ready); 0770 return true; 0771 } 0772 return static_cast <XvProcessInfo *> (process_info)->startBackend (); 0773 } 0774 0775 #include "kmplayervdr.moc" 0776 0777 #include "moc_kmplayervdr.cpp"