KMPlayer – media player
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

779 lines
30KB

  1. /* This file is part of the KMPlayer application
  2. Copyright (C) 2004 Koos Vriezen <koos.vriezen@xs4all.nl>
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  14. Boston, MA 02110-1301, USA.
  15. */
  16. #include <math.h>
  17. #include <unistd.h>
  18. #include <tqlayout.h>
  19. #include <tqlabel.h>
  20. #include <tqmap.h>
  21. #include <tqtimer.h>
  22. #include <tqpushbutton.h>
  23. #include <tqbuttongroup.h>
  24. #include <tqcheckbox.h>
  25. #include <tqtable.h>
  26. #include <tqstringlist.h>
  27. #include <tqcombobox.h>
  28. #include <tqlineedit.h>
  29. #include <tqgroupbox.h>
  30. #include <tqwhatsthis.h>
  31. #include <tqtabwidget.h>
  32. #include <tqradiobutton.h>
  33. #include <tqmessagebox.h>
  34. #include <tqpopupmenu.h>
  35. #include <tqsocket.h>
  36. #include <tqeventloop.h>
  37. #include <tdelocale.h>
  38. #include <kdebug.h>
  39. #include <tdemessagebox.h>
  40. #include <klineedit.h>
  41. #include <kurlrequester.h>
  42. #include <kcombobox.h>
  43. #include <kstatusbar.h>
  44. #include <kprocess.h>
  45. #include <tdeconfig.h>
  46. #include <tdeaction.h>
  47. #include <kiconloader.h>
  48. #include <tdelistview.h>
  49. #include <tdeversion.h>
  50. #if KDE_IS_VERSION(3, 1, 90)
  51. #include <kinputdialog.h>
  52. #endif
  53. #include "kmplayer_backend_stub.h"
  54. #include "kmplayer_callback.h"
  55. #include "kmplayerpartbase.h"
  56. #include "kmplayercontrolpanel.h"
  57. #include "kmplayerconfig.h"
  58. #include "playlistview.h"
  59. #include "viewarea.h"
  60. #include "kmplayervdr.h"
  61. #include "kmplayer.h"
  62. using namespace KMPlayer;
  63. static const char * strVDR = "VDR";
  64. static const char * strVDRPort = "Port";
  65. static const char * strXVPort = "XV Port";
  66. static const char * strXVEncoding = "XV Encoding";
  67. static const char * strXVScale = "XV Scale";
  68. KDE_NO_CDTOR_EXPORT KMPlayerPrefSourcePageVDR::KMPlayerPrefSourcePageVDR (TQWidget * parent, KMPlayer::PartBase * player)
  69. : TQFrame (parent), m_player (player) {
  70. //KURLRequester * v4ldevice;
  71. TQVBoxLayout *layout = new TQVBoxLayout (this, 5, 2);
  72. TQGridLayout *gridlayout = new TQGridLayout (1, 2);
  73. xv_port = new TDEListView (this);
  74. xv_port->addColumn (TQString());
  75. xv_port->header()->hide ();
  76. xv_port->setTreeStepSize (15);
  77. //xv_port->setRootIsDecorated (true);
  78. //xv_port->setSorting (-1);
  79. TQListViewItem * vitem = new TQListViewItem (xv_port, i18n ("XVideo port"));
  80. vitem->setOpen (true);
  81. TQWhatsThis::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"));
  82. TQLabel * label = new TQLabel (i18n ("Communication port:"), this);
  83. gridlayout->addWidget (label, 0, 0);
  84. tcp_port = new TQLineEdit ("", this);
  85. TQWhatsThis::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."));
  86. gridlayout->addWidget (tcp_port, 0, 1);
  87. layout->addWidget (xv_port);
  88. layout->addLayout (gridlayout);
  89. scale = new TQButtonGroup (2, Qt::Vertical, i18n ("Scale"), this);
  90. new TQRadioButton (i18n ("4:3"), scale);
  91. new TQRadioButton (i18n ("16:9"), scale);
  92. TQWhatsThis::add (scale, i18n ("Aspects to use when viewing VDR"));
  93. scale->setButton (0);
  94. layout->addWidget (scale);
  95. layout->addItem (new TQSpacerItem (5, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding));
  96. }
  97. KDE_NO_CDTOR_EXPORT KMPlayerPrefSourcePageVDR::~KMPlayerPrefSourcePageVDR () {}
  98. KDE_NO_EXPORT void KMPlayerPrefSourcePageVDR::showEvent (TQShowEvent *) {
  99. XVideo * xvideo = static_cast<XVideo *>(m_player->players()["xvideo"]);
  100. if (!xvideo->configDocument ())
  101. xvideo->getConfigData ();
  102. }
  103. //-----------------------------------------------------------------------------
  104. static const char * cmd_chan_query = "CHAN\n";
  105. static const char * cmd_list_channels = "LSTC\n";
  106. static const char * cmd_volume_query = "VOLU\n";
  107. class VDRCommand {
  108. public:
  109. KDE_NO_CDTOR_EXPORT VDRCommand (const char * c, VDRCommand * n=0L)
  110. : command (strdup (c)), next (n) {}
  111. KDE_NO_CDTOR_EXPORT ~VDRCommand () { free (command); }
  112. char * command;
  113. VDRCommand * next;
  114. };
  115. //-----------------------------------------------------------------------------
  116. KDE_NO_CDTOR_EXPORT KMPlayerVDRSource::KMPlayerVDRSource (KMPlayerApp * app)
  117. : KMPlayer::Source (TQString ("VDR"), app->player (), "vdrsource"),
  118. m_app (app),
  119. m_configpage (0),
  120. m_socket (new TQSocket (this)),
  121. commands (0L),
  122. channel_timer (0),
  123. timeout_timer (0),
  124. finish_timer (0),
  125. tcp_port (0),
  126. m_stored_volume (0) {
  127. memset (m_actions, 0, sizeof (TDEAction *) * int (act_last));
  128. m_player->settings ()->addPage (this);
  129. connect (m_socket, TQT_SIGNAL (connectionClosed()), this, TQT_SLOT(disconnected()));
  130. connect (m_socket, TQT_SIGNAL (connected ()), this, TQT_SLOT (connected ()));
  131. connect (m_socket, TQT_SIGNAL (readyRead ()), this, TQT_SLOT (readyRead ()));
  132. connect (m_socket, TQT_SIGNAL (error (int)), this, TQT_SLOT (socketError (int)));
  133. }
  134. KDE_NO_CDTOR_EXPORT KMPlayerVDRSource::~KMPlayerVDRSource () {}
  135. KDE_NO_CDTOR_EXPORT void KMPlayerVDRSource::waitForConnectionClose () {
  136. if (timeout_timer) {
  137. finish_timer = startTimer (500);
  138. kdDebug () << "VDR connection not yet closed" << endl;
  139. TQApplication::eventLoop ()->enterLoop ();
  140. kdDebug () << "VDR connection:" << (m_socket->state () == TQSocket::Connected) << endl;
  141. timeout_timer = 0;
  142. }
  143. }
  144. KDE_NO_EXPORT bool KMPlayerVDRSource::hasLength () {
  145. return false;
  146. }
  147. KDE_NO_EXPORT bool KMPlayerVDRSource::isSeekable () {
  148. return true;
  149. }
  150. KDE_NO_EXPORT TQString KMPlayerVDRSource::prettyName () {
  151. return i18n ("VDR");
  152. }
  153. KDE_NO_EXPORT void KMPlayerVDRSource::activate () {
  154. last_channel = 0;
  155. connect (this, TQT_SIGNAL (startPlaying ()), this, TQT_SLOT (processStarted()));
  156. connect (this, TQT_SIGNAL (stopPlaying ()), this, TQT_SLOT (processStopped ()));
  157. KMPlayer::ControlPanel * panel = m_app->view()->controlPanel ();
  158. panel->button (KMPlayer::ControlPanel::button_red)->show ();
  159. panel->button (KMPlayer::ControlPanel::button_green)->show ();
  160. panel->button (KMPlayer::ControlPanel::button_yellow)->show ();
  161. panel->button (KMPlayer::ControlPanel::button_blue)->show ();
  162. panel->button (KMPlayer::ControlPanel::button_pause)->hide ();
  163. panel->button (KMPlayer::ControlPanel::button_record)->hide ();
  164. connect (panel->volumeBar (), TQT_SIGNAL (volumeChanged (int)), this, TQT_SLOT (volumeChanged (int)));
  165. connect (panel->button (KMPlayer::ControlPanel::button_red), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyRed ()));
  166. connect (panel->button (KMPlayer::ControlPanel::button_green), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyGreen ()));
  167. connect (panel->button (KMPlayer::ControlPanel::button_yellow), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyYellow ()));
  168. connect (panel->button (KMPlayer::ControlPanel::button_blue), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyBlue ()));
  169. setAspect (m_document, scale ? 16.0/9 : 1.33);
  170. if (!m_url.protocol ().compare ("kmplayer"))
  171. m_request_jump = KURL::decode_string (m_url.path ()).mid (1);
  172. setURL (KURL (TQString ("vdr://localhost:%1").arg (tcp_port)));
  173. TQTimer::singleShot (0, m_player, TQT_SLOT (play ()));
  174. }
  175. KDE_NO_EXPORT void KMPlayerVDRSource::deactivate () {
  176. disconnect (m_socket, TQT_SIGNAL (error (int)), this, TQT_SLOT (socketError (int)));
  177. if (m_player->view ()) {
  178. disconnect (this, TQT_SIGNAL(startPlaying()), this, TQT_SLOT(processStarted()));
  179. disconnect (this, TQT_SIGNAL (stopPlaying()), this, TQT_SLOT(processStopped()));
  180. KMPlayer::ControlPanel * panel = m_app->view()->controlPanel ();
  181. disconnect (panel->volumeBar (), TQT_SIGNAL (volumeChanged (int)), this, TQT_SLOT (volumeChanged (int)));
  182. disconnect (panel->button (KMPlayer::ControlPanel::button_red), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyRed ()));
  183. disconnect (panel->button (KMPlayer::ControlPanel::button_green), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyGreen ()));
  184. disconnect (panel->button (KMPlayer::ControlPanel::button_yellow), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyYellow ()));
  185. disconnect (panel->button (KMPlayer::ControlPanel::button_blue), TQT_SIGNAL (clicked ()), this, TQT_SLOT (keyBlue ()));
  186. }
  187. processStopped ();
  188. m_request_jump.truncate (0);
  189. }
  190. KDE_NO_EXPORT void KMPlayerVDRSource::playCurrent () {
  191. if (m_player->process ())
  192. m_player->process ()->play (this, current ()); // FIXME HACK
  193. }
  194. KDE_NO_EXPORT void KMPlayerVDRSource::processStopped () {
  195. if (m_socket->state () == TQSocket::Connected) {
  196. queueCommand (TQString ("VOLU %1\n").arg (m_stored_volume).ascii ());
  197. queueCommand ("QUIT\n");
  198. }
  199. }
  200. KDE_NO_EXPORT void KMPlayerVDRSource::processStarted () {
  201. m_socket->connectToHost ("127.0.0.1", tcp_port);
  202. commands = new VDRCommand ("connect", commands);
  203. }
  204. #define DEF_ACT(i,text,pix,scut,slot,name) \
  205. m_actions [i] = new TDEAction (text, TQString (pix), TDEShortcut (scut), this, slot, m_app->actionCollection (), name); \
  206. m_fullscreen_actions [i] = new TDEAction (text, TDEShortcut (scut), this, slot, m_app->view ()->viewArea ()->actionCollection (), name)
  207. KDE_NO_EXPORT void KMPlayerVDRSource::connected () {
  208. queueCommand (cmd_list_channels);
  209. queueCommand (cmd_volume_query);
  210. killTimer (channel_timer);
  211. channel_timer = startTimer (3000);
  212. TDEAction * action = m_app->actionCollection ()->action ("vdr_connect");
  213. action->setIcon (TQString ("connect_no"));
  214. action->setText (i18n ("Dis&connect"));
  215. DEF_ACT (act_up, i18n ("VDR Key Up"), "go-up", , TQT_SLOT (keyUp ()), "vdr_key_up");
  216. DEF_ACT (act_down, i18n ("VDR Key Down"), "go-down", , TQT_SLOT (keyDown ()), "vdr_key_down");
  217. DEF_ACT (act_back, i18n ("VDR Key Back"), "back", , TQT_SLOT (keyBack ()), "vdr_key_back");
  218. DEF_ACT (act_ok, i18n ("VDR Key Ok"), "ok", , TQT_SLOT (keyOk ()), "vdr_key_ok");
  219. DEF_ACT (act_setup, i18n ("VDR Key Setup"), "configure", , TQT_SLOT (keySetup ()), "vdr_key_setup");
  220. DEF_ACT (act_channels, i18n ("VDR Key Channels"), "player_playlist", , TQT_SLOT (keyChannels ()), "vdr_key_channels");
  221. DEF_ACT (act_menu, i18n ("VDR Key Menu"), "showmenu", , TQT_SLOT (keyMenu ()), "vdr_key_menu");
  222. DEF_ACT (act_red, i18n ("VDR Key Red"), "red", , TQT_SLOT (keyRed ()), "vdr_key_red");
  223. DEF_ACT (act_green, i18n ("VDR Key Green"), "green", , TQT_SLOT (keyGreen ()), "vdr_key_green");
  224. DEF_ACT (act_yellow, i18n ("VDR Key Yellow"), "yellow", , TQT_SLOT (keyYellow ()), "vdr_key_yellow");
  225. DEF_ACT (act_blue, i18n ("VDR Key Blue"), "blue", , TQT_SLOT (keyBlue ()), "vdr_key_blue");
  226. DEF_ACT (act_custom, "VDR Custom Command", "application-x-executable", , TQT_SLOT (customCmd ()), "vdr_key_custom");
  227. m_app->initMenu (); // update menu and toolbar
  228. DEF_ACT (act_0, i18n ("VDR Key 0"), "0", TQt::Key_0, TQT_SLOT (key0 ()), "vdr_key_0");
  229. DEF_ACT (act_1, i18n ("VDR Key 1"), "1", TQt::Key_1, TQT_SLOT (key1 ()), "vdr_key_1");
  230. DEF_ACT (act_2, i18n ("VDR Key 2"), "2", TQt::Key_2, TQT_SLOT (key2 ()), "vdr_key_2");
  231. DEF_ACT (act_3, i18n ("VDR Key 3"), "3", TQt::Key_3, TQT_SLOT (key3 ()), "vdr_key_3");
  232. DEF_ACT (act_4, i18n ("VDR Key 4"), "4", TQt::Key_4, TQT_SLOT (key4 ()), "vdr_key_4");
  233. DEF_ACT (act_5, i18n ("VDR Key 5"), "5", TQt::Key_5, TQT_SLOT (key5 ()), "vdr_key_5");
  234. DEF_ACT (act_6, i18n ("VDR Key 6"), "6", TQt::Key_6, TQT_SLOT (key6 ()), "vdr_key_6");
  235. DEF_ACT (act_7, i18n ("VDR Key 7"), "7", TQt::Key_7, TQT_SLOT (key7 ()), "vdr_key_7");
  236. DEF_ACT (act_8, i18n ("VDR Key 8"), "8", TQt::Key_8, TQT_SLOT (key8 ()), "vdr_key_8");
  237. DEF_ACT (act_9, i18n ("VDR Key 9"), "9", TQt::Key_9, TQT_SLOT (key9 ()), "vdr_key_9");
  238. //KMPlayer::ViewLayer * layer = m_app->view ()->viewArea ();
  239. for (int i = 0; i < int (act_last); ++i)
  240. // somehow, the configured shortcuts only show up after createGUI() call
  241. m_fullscreen_actions [i]->setShortcut (m_actions [i]->shortcut ());
  242. // m_fullscreen_actions[i]->plug (layer);
  243. }
  244. #undef DEF_ACT
  245. KDE_NO_EXPORT void KMPlayerVDRSource::disconnected () {
  246. kdDebug() << "disconnected " << commands << endl;
  247. if (finish_timer) {
  248. deleteCommands ();
  249. return;
  250. }
  251. setURL (KURL (TQString ("vdr://localhost:%1").arg (tcp_port)));
  252. if (channel_timer && m_player->source () == this)
  253. m_player->process ()->quit ();
  254. deleteCommands ();
  255. TDEAction * action = m_app->actionCollection ()->action ("vdr_connect");
  256. action->setIcon (TQString ("connect_established"));
  257. action->setText (i18n ("&Connect"));
  258. m_app->guiFactory ()->removeClient (m_app);// crash w/ m_actions[i]->unplugAll (); in for loop below
  259. for (int i = 0; i < int (act_last); ++i)
  260. if (m_player->view () && m_actions[i]) {
  261. m_fullscreen_actions[i]->unplug (m_app->view()->viewArea());
  262. delete m_actions[i];
  263. delete m_fullscreen_actions[i];
  264. }
  265. m_app->initMenu ();
  266. }
  267. KDE_NO_EXPORT void KMPlayerVDRSource::toggleConnected () {
  268. if (m_socket->state () == TQSocket::Connected) {
  269. queueCommand ("QUIT\n");
  270. killTimer (channel_timer);
  271. channel_timer = 0;
  272. } else {
  273. m_socket->connectToHost ("127.0.0.1", tcp_port);
  274. commands = new VDRCommand ("connect", commands);
  275. }
  276. }
  277. KDE_NO_EXPORT void KMPlayerVDRSource::volumeChanged (int val) {
  278. queueCommand (TQString ("VOLU %1\n").arg (int (sqrt (255 * 255 * val / 100))).ascii ());
  279. }
  280. static struct ReadBuf {
  281. char * buf;
  282. int length;
  283. KDE_NO_CDTOR_EXPORT ReadBuf () : buf (0L), length (0) {}
  284. KDE_NO_CDTOR_EXPORT ~ReadBuf () {
  285. clear ();
  286. }
  287. KDE_NO_EXPORT void operator += (const char * s) {
  288. int l = strlen (s);
  289. char * b = new char [length + l + 1];
  290. if (length)
  291. strcpy (b, buf);
  292. strcpy (b + length, s);
  293. length += l;
  294. delete buf;
  295. buf = b;
  296. }
  297. KDE_NO_EXPORT TQCString mid (int p) {
  298. return TQCString (buf + p);
  299. }
  300. KDE_NO_EXPORT TQCString left (int p) {
  301. return TQCString (buf, p);
  302. }
  303. KDE_NO_EXPORT TQCString getReadLine ();
  304. KDE_NO_EXPORT void clear () {
  305. delete [] buf;
  306. buf = 0;
  307. length = 0;
  308. }
  309. } readbuf;
  310. KDE_NO_EXPORT TQCString ReadBuf::getReadLine () {
  311. TQCString out;
  312. if (!length)
  313. return out;
  314. int p = strcspn (buf, "\r\n");
  315. if (p < length) {
  316. int skip = strspn (buf + p, "\r\n");
  317. out = left (p+1);
  318. int nl = length - p - skip;
  319. memmove (buf, buf + p + skip, nl + 1);
  320. length = nl;
  321. }
  322. return out;
  323. }
  324. KDE_NO_EXPORT void KMPlayerVDRSource::readyRead () {
  325. KMPlayer::View * v = finish_timer ? 0L : static_cast <KMPlayer::View *> (m_player->view ());
  326. long nr = m_socket->bytesAvailable();
  327. char * data = new char [nr + 1];
  328. m_socket->readBlock (data, nr);
  329. data [nr] = 0;
  330. readbuf += data;
  331. TQCString line = readbuf.getReadLine ();
  332. if (commands) {
  333. bool cmd_done = false;
  334. while (!line.isEmpty ()) {
  335. bool toconsole = true;
  336. cmd_done = (line.length () > 3 && line[3] == ' '); // from svdrpsend.pl
  337. // kdDebug () << "readyRead " << cmd_done << " " << commands->command << endl;
  338. if (!strcmp (commands->command, cmd_list_channels) && m_document) {
  339. int p = line.find (';');
  340. int q = line.find (':');
  341. if (q > 0 && (p < 0 || q < p))
  342. p = q;
  343. if (p > 0)
  344. line.truncate (p);
  345. TQString channel_name = line.mid (4);
  346. m_document->appendChild (new KMPlayer::GenericMrl (m_document, TQString ("kmplayer://vdrsource/%1").arg(channel_name), channel_name));
  347. if (cmd_done) {
  348. m_player->updateTree ();
  349. if (!m_request_jump.isEmpty ()) {
  350. jump (m_request_jump);
  351. m_request_jump.truncate (0);
  352. }
  353. }
  354. toconsole = false;
  355. } else if (!strcmp (commands->command, cmd_chan_query)) {
  356. if (v && line.length () > 4) {
  357. TQString ch = line.mid (4);
  358. setTitle (ch);
  359. KMPlayer::PlayListItem * lvi = static_cast <KMPlayer::PlayListItem *> (v->playList ()->findItem (ch, 0));
  360. if (lvi && lvi->node != m_last_channel) {
  361. KMPlayer::PlayListItem * si = static_cast <KMPlayer::PlayListItem *> (v->playList ()->selectedItem ());
  362. bool jump_selection = (si && (si->node == m_document || si->node == m_last_channel));
  363. if (m_last_channel)
  364. m_last_channel->setState (KMPlayer::Node::state_finished);
  365. m_last_channel = lvi->node;
  366. if (m_last_channel)
  367. m_last_channel->setState (KMPlayer::Node::state_began);
  368. if (jump_selection) {
  369. v->playList ()->setSelected (lvi, true);
  370. v->playList ()->ensureItemVisible (lvi);
  371. }
  372. v->playList ()->triggerUpdate ();
  373. }
  374. //v->playList ()->selectItem (ch);
  375. int c = strtol(ch.ascii(), 0L, 10);
  376. if (c != last_channel) {
  377. last_channel = c;
  378. m_app->statusBar ()->changeItem (TQString::number (c),
  379. id_status_timer);
  380. }
  381. }
  382. } else if (cmd_done && !strcmp(commands->command,cmd_volume_query)){
  383. int pos = line.findRev (TQChar (' '));
  384. if (pos > 0) {
  385. TQString vol = line.mid (pos + 1);
  386. if (!vol.compare ("mute"))
  387. m_stored_volume = 0;
  388. else
  389. m_stored_volume = vol.toInt ();
  390. if (m_stored_volume == 0)
  391. volumeChanged (m_app->view ()->controlPanel ()->volumeBar ()->value ());
  392. }
  393. }
  394. if (v && toconsole)
  395. v->addText (TQString (line), true);
  396. line = readbuf.getReadLine ();
  397. }
  398. if (cmd_done) {
  399. VDRCommand * c = commands->next;
  400. delete commands;
  401. commands = c;
  402. if (commands)
  403. sendCommand ();
  404. else {
  405. killTimer (timeout_timer);
  406. timeout_timer = 0;
  407. }
  408. }
  409. }
  410. delete [] data;
  411. }
  412. KDE_NO_EXPORT void KMPlayerVDRSource::socketError (int code) {
  413. if (code == TQSocket::ErrHostNotFound) {
  414. KMessageBox::error (m_configpage, i18n ("Host not found"), i18n ("Error"));
  415. } else if (code == TQSocket::ErrConnectionRefused) {
  416. KMessageBox::error (m_configpage, i18n ("Connection refused"), i18n ("Error"));
  417. }
  418. }
  419. KDE_NO_EXPORT void KMPlayerVDRSource::queueCommand (const char * cmd) {
  420. if (m_player->source () != this)
  421. return;
  422. if (!commands) {
  423. readbuf.clear ();
  424. commands = new VDRCommand (cmd);
  425. if (m_socket->state () == TQSocket::Connected) {
  426. sendCommand ();
  427. } else {
  428. m_socket->connectToHost ("127.0.0.1", tcp_port);
  429. commands = new VDRCommand ("connect", commands);
  430. }
  431. } else {
  432. VDRCommand * c = commands;
  433. for (int i = 0; i < 10; ++i, c = c->next)
  434. if (!c->next) {
  435. c->next = new VDRCommand (cmd);
  436. break;
  437. }
  438. }
  439. }
  440. KDE_NO_EXPORT void KMPlayerVDRSource::queueCommand (const char * cmd, int t) {
  441. queueCommand (cmd);
  442. killTimer (channel_timer);
  443. channel_timer = startTimer (t);
  444. }
  445. KDE_NO_EXPORT void KMPlayerVDRSource::sendCommand () {
  446. //kdDebug () << "sendCommand " << commands->command << endl;
  447. m_socket->writeBlock (commands->command, strlen(commands->command));
  448. m_socket->flush ();
  449. killTimer (timeout_timer);
  450. timeout_timer = startTimer (30000);
  451. }
  452. KDE_NO_EXPORT void KMPlayerVDRSource::customCmd () {
  453. #if KDE_IS_VERSION(3, 1, 90)
  454. TQString 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:"), TQString(), 0, m_player->view ());
  455. if (!cmd.isEmpty ())
  456. queueCommand (TQString (cmd + TQChar ('\n')).local8Bit ());
  457. #endif
  458. }
  459. KDE_NO_EXPORT void KMPlayerVDRSource::timerEvent (TQTimerEvent * e) {
  460. if (e->timerId () == timeout_timer || e->timerId () == finish_timer) {
  461. deleteCommands ();
  462. } else if (e->timerId () == channel_timer) {
  463. queueCommand (cmd_chan_query);
  464. killTimer (channel_timer);
  465. channel_timer = startTimer (30000);
  466. }
  467. }
  468. KDE_NO_EXPORT void KMPlayerVDRSource::deleteCommands () {
  469. killTimer (timeout_timer);
  470. timeout_timer = 0;
  471. killTimer (channel_timer);
  472. channel_timer = 0;
  473. for (VDRCommand * c = commands; c; c = commands) {
  474. commands = commands->next;
  475. delete c;
  476. }
  477. readbuf.clear ();
  478. if (finish_timer) {
  479. killTimer (finish_timer);
  480. TQApplication::eventLoop ()->exitLoop ();
  481. }
  482. }
  483. KDE_NO_EXPORT void KMPlayerVDRSource::jump (KMPlayer::NodePtr e) {
  484. if (!e->isPlayable ()) return;
  485. m_current = e;
  486. jump (e->mrl ()->pretty_name);
  487. }
  488. KDE_NO_EXPORT void KMPlayerVDRSource::jump (const TQString & channel) {
  489. TQCString c ("CHAN ");
  490. TQCString ch = channel.local8Bit ();
  491. int p = ch.find (' ');
  492. if (p > 0)
  493. c += ch.left (p);
  494. else
  495. c += ch; // hope for the best ..
  496. c += '\n';
  497. queueCommand (c);
  498. }
  499. KDE_NO_EXPORT void KMPlayerVDRSource::forward () {
  500. queueCommand ("CHAN +\n", 1000);
  501. }
  502. KDE_NO_EXPORT void KMPlayerVDRSource::backward () {
  503. queueCommand ("CHAN -\n", 1000);
  504. }
  505. KDE_NO_EXPORT void KMPlayerVDRSource::keyUp () {
  506. queueCommand ("HITK UP\n", 1000);
  507. }
  508. KDE_NO_EXPORT void KMPlayerVDRSource::keyDown () {
  509. queueCommand ("HITK DOWN\n", 1000);
  510. }
  511. KDE_NO_EXPORT void KMPlayerVDRSource::keyBack () {
  512. queueCommand ("HITK BACK\n");
  513. }
  514. KDE_NO_EXPORT void KMPlayerVDRSource::keyOk () {
  515. queueCommand ("HITK OK\n");
  516. }
  517. KDE_NO_EXPORT void KMPlayerVDRSource::keySetup () {
  518. queueCommand ("HITK SETUP\n");
  519. }
  520. KDE_NO_EXPORT void KMPlayerVDRSource::keyChannels () {
  521. queueCommand ("HITK CHANNELS\n");
  522. }
  523. KDE_NO_EXPORT void KMPlayerVDRSource::keyMenu () {
  524. queueCommand ("HITK MENU\n");
  525. }
  526. KDE_NO_EXPORT void KMPlayerVDRSource::key0 () {
  527. queueCommand ("HITK 0\n", 2000);
  528. }
  529. KDE_NO_EXPORT void KMPlayerVDRSource::key1 () {
  530. queueCommand ("HITK 1\n", 2000);
  531. }
  532. KDE_NO_EXPORT void KMPlayerVDRSource::key2 () {
  533. queueCommand ("HITK 2\n", 2000);
  534. }
  535. KDE_NO_EXPORT void KMPlayerVDRSource::key3 () {
  536. queueCommand ("HITK 3\n", 2000);
  537. }
  538. KDE_NO_EXPORT void KMPlayerVDRSource::key4 () {
  539. queueCommand ("HITK 4\n", 2000);
  540. }
  541. KDE_NO_EXPORT void KMPlayerVDRSource::key5 () {
  542. queueCommand ("HITK 5\n", 2000);
  543. }
  544. KDE_NO_EXPORT void KMPlayerVDRSource::key6 () {
  545. queueCommand ("HITK 6\n", 2000);
  546. }
  547. KDE_NO_EXPORT void KMPlayerVDRSource::key7 () {
  548. queueCommand ("HITK 7\n", 2000);
  549. }
  550. KDE_NO_EXPORT void KMPlayerVDRSource::key8 () {
  551. queueCommand ("HITK 8\n", 2000);
  552. }
  553. KDE_NO_EXPORT void KMPlayerVDRSource::key9 () {
  554. queueCommand ("HITK 9\n", 2000);
  555. }
  556. KDE_NO_EXPORT void KMPlayerVDRSource::keyRed () {
  557. queueCommand ("HITK RED\n");
  558. }
  559. KDE_NO_EXPORT void KMPlayerVDRSource::keyGreen () {
  560. queueCommand ("HITK GREEN\n");
  561. }
  562. KDE_NO_EXPORT void KMPlayerVDRSource::keyYellow () {
  563. queueCommand ("HITK YELLOW\n");
  564. }
  565. KDE_NO_EXPORT void KMPlayerVDRSource::keyBlue () {
  566. queueCommand ("HITK BLUE\n");
  567. }
  568. KDE_NO_EXPORT void KMPlayerVDRSource::write (TDEConfig * m_config) {
  569. m_config->setGroup (strVDR);
  570. m_config->writeEntry (strVDRPort, tcp_port);
  571. m_config->writeEntry (strXVPort, m_xvport);
  572. m_config->writeEntry (strXVEncoding, m_xvencoding);
  573. m_config->writeEntry (strXVScale, scale);
  574. }
  575. KDE_NO_EXPORT void KMPlayerVDRSource::read (TDEConfig * m_config) {
  576. m_config->setGroup (strVDR);
  577. tcp_port = m_config->readNumEntry (strVDRPort, 2001);
  578. m_xvport = m_config->readNumEntry (strXVPort, 0);
  579. m_xvencoding = m_config->readNumEntry (strXVEncoding, 0);
  580. scale = m_config->readNumEntry (strXVScale, 0);
  581. }
  582. struct XVTreeItem : public TQListViewItem {
  583. XVTreeItem (TQListViewItem *parent, const TQString & t, int p, int e)
  584. : TQListViewItem (parent, t), port (p), encoding (e) {}
  585. int port;
  586. int encoding;
  587. };
  588. KDE_NO_EXPORT void KMPlayerVDRSource::sync (bool fromUI) {
  589. XVideo * xvideo = static_cast<XVideo *>(m_player->players()["xvideo"]);
  590. if (fromUI) {
  591. tcp_port = m_configpage->tcp_port->text ().toInt ();
  592. scale = m_configpage->scale->id (m_configpage->scale->selected ());
  593. setAspect (m_document, scale ? 16.0/9 : 1.25);
  594. XVTreeItem * vitem = dynamic_cast <XVTreeItem *> (m_configpage->xv_port->selectedItem ());
  595. if (vitem) {
  596. m_xvport = vitem->port;
  597. m_xvencoding = vitem->encoding;
  598. }
  599. } else {
  600. m_configpage->tcp_port->setText (TQString::number (tcp_port));
  601. m_configpage->scale->setButton (scale);
  602. TQListViewItem * vitem = m_configpage->xv_port->firstChild ();
  603. NodePtr configdoc = xvideo->configDocument ();
  604. if (configdoc && configdoc->firstChild ()) {
  605. for (TQListViewItem *i=vitem->firstChild(); i; i=vitem->firstChild())
  606. delete i;
  607. NodePtr node = configdoc->firstChild ();
  608. for (node = node->firstChild (); node; node = node->nextSibling()) {
  609. if (!node->isElementNode ())
  610. continue; // some text sneaked in ?
  611. Element * elm = convertNode <Element> (node);
  612. if (elm->getAttribute (KMPlayer::StringPool::attr_type) !=
  613. TQString ("tree"))
  614. continue;
  615. for (NodePtr n = elm->firstChild (); n; n = n->nextSibling ()) {
  616. if (!n->isElementNode () || strcmp (n->nodeName (), "Port"))
  617. continue;
  618. Element * e = convertNode <Element> (n);
  619. TQString portatt = e->getAttribute (
  620. KMPlayer::StringPool::attr_value);
  621. int port;
  622. TQListViewItem *pi = new TQListViewItem (vitem, i18n ("Port ") + portatt);
  623. port = portatt.toInt ();
  624. for (NodePtr in=e->firstChild(); in; in=in->nextSibling()) {
  625. if (!in->isElementNode () ||
  626. strcmp (in->nodeName (), "Input"))
  627. continue;
  628. Element * i = convertNode <Element> (in);
  629. TQString inp = i->getAttribute (
  630. KMPlayer::StringPool::attr_name);
  631. int enc = i->getAttribute (
  632. KMPlayer::StringPool::attr_value).toInt ();
  633. TQListViewItem * ii = new XVTreeItem(pi, inp, port, enc);
  634. if (m_xvport == port && enc == m_xvencoding) {
  635. ii->setSelected (true);
  636. m_configpage->xv_port->ensureItemVisible (ii);
  637. }
  638. }
  639. }
  640. }
  641. } else // wait for showEvent
  642. connect (xvideo, TQT_SIGNAL (configReceived()), this, TQT_SLOT (configReceived()));
  643. }
  644. }
  645. KDE_NO_EXPORT void KMPlayerVDRSource::configReceived () {
  646. XVideo * xvideo = static_cast<XVideo *>(m_player->players()["xvideo"]);
  647. disconnect (xvideo, TQT_SIGNAL (configReceived()), this, TQT_SLOT (configReceived()));
  648. sync (false);
  649. }
  650. KDE_NO_EXPORT void KMPlayerVDRSource::prefLocation (TQString & item, TQString & icon, TQString & tab) {
  651. item = i18n ("Source");
  652. icon = TQString ("text-x-src");
  653. tab = i18n ("VDR");
  654. }
  655. KDE_NO_EXPORT TQFrame * KMPlayerVDRSource::prefPage (TQWidget * parent) {
  656. if (!m_configpage)
  657. m_configpage = new KMPlayerPrefSourcePageVDR (parent, m_player);
  658. return m_configpage;
  659. }
  660. KDE_NO_EXPORT bool KMPlayerVDRSource::requestPlayURL (KMPlayer::NodePtr) {
  661. return true;
  662. }
  663. KDE_NO_EXPORT void KMPlayerVDRSource::stateElementChanged (KMPlayer::Node *, KMPlayer::Node::State, KMPlayer::Node::State) {
  664. }
  665. //-----------------------------------------------------------------------------
  666. static const char * xv_supported [] = {
  667. "tvsource", "vdrsource", 0L
  668. };
  669. KDE_NO_CDTOR_EXPORT XVideo::XVideo (TQObject * parent, Settings * settings)
  670. : KMPlayer::CallbackProcess (parent, settings, "xvideo", i18n ("X&Video")) {
  671. m_supported_sources = xv_supported;
  672. //m_player->settings ()->addPage (m_configpage);
  673. }
  674. KDE_NO_CDTOR_EXPORT XVideo::~XVideo () {}
  675. KDE_NO_EXPORT bool XVideo::ready (KMPlayer::Viewer * v) {
  676. if (playing ()) {
  677. return true;
  678. }
  679. initProcess (v);
  680. TQString cmd = TQString ("kxvplayer -wid %3 -cb %4").arg (viewer ()->embeddedWinId ()).arg (dcopName ());
  681. if (m_have_config == config_unknown || m_have_config == config_probe)
  682. cmd += TQString (" -c");
  683. if (m_source) {
  684. int xv_port = m_source->xvPort ();
  685. int xv_encoding = m_source->xvEncoding ();
  686. int freq = m_source->frequency ();
  687. cmd += TQString (" -port %1 -enc %2 -norm \"%3\"").arg (xv_port).arg (xv_encoding).arg (m_source->videoNorm ());
  688. if (freq > 0)
  689. cmd += TQString (" -freq %1").arg (freq);
  690. }
  691. fprintf (stderr, "%s\n", cmd.latin1 ());
  692. *m_process << cmd;
  693. m_process->start (TDEProcess::NotifyOnExit, TDEProcess::All);
  694. return m_process->isRunning ();
  695. }
  696. #include "kmplayervdr.moc"