TDE core libraries
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.

447 lines
11KB

  1. /*
  2. This file is part of KDE/aRts (Noatun) - xine integration
  3. Copyright (C) 2002 Ewald Snel <ewald@rambo.its.tudelft.nl>
  4. Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License version 2 as published by the Free Software Foundation.
  8. */
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. #include <time.h>
  13. #ifdef HAVE_USLEEP
  14. #include <unistd.h>
  15. #endif
  16. #include <tqaccel.h>
  17. #include <tqcursor.h>
  18. #if defined Q_WS_X11 && ! defined K_WS_QTONLY
  19. #include <X11/Xlib.h>
  20. #include <X11/Xutil.h>
  21. #else
  22. #define XEvent void
  23. #endif
  24. #include <tdeaction.h>
  25. #include <tdelocale.h>
  26. #include "kvideowidget.h"
  27. class KFullscreenVideoWidget : public KVideoWidget
  28. {
  29. public:
  30. KFullscreenVideoWidget( KVideoWidget *parent = 0, const char *name = 0 );
  31. protected:
  32. virtual void windowActivationChange( bool );
  33. virtual bool x11Event( XEvent *event );
  34. private:
  35. KVideoWidget *videoWidget;
  36. };
  37. KFullscreenVideoWidget::KFullscreenVideoWidget( KVideoWidget *parent, const char *name )
  38. : KVideoWidget( 0, name )
  39. {
  40. this->videoWidget = parent;
  41. setEraseColor( black );
  42. setCursor(TQCursor(Qt::BlankCursor));
  43. }
  44. void KFullscreenVideoWidget::windowActivationChange( bool )
  45. {
  46. if (!isActiveWindow())
  47. {
  48. videoWidget->setWindowed();
  49. }
  50. }
  51. bool KFullscreenVideoWidget::x11Event( XEvent *event )
  52. {
  53. #if defined Q_WS_X11 && ! defined K_WS_QTONLY
  54. if (event->type == ClientMessage &&
  55. event->xclient.message_type ==
  56. XInternAtom( tqt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
  57. {
  58. videoWidget->resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
  59. }
  60. #endif
  61. return false;
  62. }
  63. KVideoWidget::KVideoWidget( KXMLGUIClient *clientParent, TQWidget *parent, const char *name, WFlags f )
  64. : KXMLGUIClient( clientParent ),
  65. TQWidget( parent, name, f )
  66. {
  67. init();
  68. // ???
  69. TQString toolbarName = i18n("Video Toolbar");
  70. setXML(TQString("<!DOCTYPE kpartgui>\n<kpartgui name=\"kvideowidget\" version=\"1\"><MenuBar><Menu name=\"edit\"><Separator/><Action name=\"double_size\"/><Action name=\"normal_size\"/><Action name=\"half_size\"/><Separator/><Action name=\"fullscreen_mode\"/></Menu></MenuBar><Toolbar name=\"VideoToolbar\"><text>Video Toolbar</text><Action name=\"fullscreen_mode\"/></Toolbar></kpartgui>"), true);
  71. }
  72. KVideoWidget::KVideoWidget( TQWidget *parent, const char *name, WFlags f )
  73. : TQWidget( parent, name, f )
  74. {
  75. init();
  76. }
  77. void KVideoWidget::init(void)
  78. {
  79. setMinimumSize(0, 0);
  80. setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
  81. setFocusPolicy( TQ_ClickFocus );
  82. fullscreenWidget = 0;
  83. poVideo = Arts::VideoPlayObject::null();
  84. videoWidth = 0;
  85. videoHeight = 0;
  86. // Setup actions
  87. new TDEToggleAction( i18n("Fullscreen &Mode"), "window_fullscreen",
  88. CTRL+SHIFT+Key_F, TQT_TQOBJECT(this), TQT_SLOT(fullscreenActivated()),
  89. actionCollection(), "fullscreen_mode" );
  90. new TDERadioAction( i18n("&Half Size"), ALT+Key_0,
  91. TQT_TQOBJECT(this), TQT_SLOT(halfSizeActivated()),
  92. actionCollection(), "half_size" );
  93. new TDERadioAction( i18n("&Normal Size"), ALT+Key_1,
  94. TQT_TQOBJECT(this), TQT_SLOT(normalSizeActivated()),
  95. actionCollection(), "normal_size" );
  96. new TDERadioAction( i18n("&Double Size"), ALT+Key_2,
  97. TQT_TQOBJECT(this), TQT_SLOT(doubleSizeActivated()),
  98. actionCollection(), "double_size" );
  99. ((TDEToggleAction *)action( "half_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
  100. ((TDEToggleAction *)action( "normal_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
  101. ((TDEToggleAction *)action( "double_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
  102. action("double_size")->setEnabled(false);
  103. action("half_size")->setEnabled(false);
  104. action("normal_size")->setEnabled(false);
  105. action("fullscreen_mode")->setEnabled(false);
  106. }
  107. KVideoWidget::~KVideoWidget()
  108. {
  109. if (isEmbedded())
  110. {
  111. poVideo.x11WindowId( -1 );
  112. poVideo = Arts::VideoPlayObject::null();
  113. }
  114. delete fullscreenWidget;
  115. }
  116. void KVideoWidget::embed( Arts::VideoPlayObject vpo )
  117. {
  118. bool enable;
  119. if (vpo.isNull())
  120. {
  121. if (isEmbedded())
  122. {
  123. poVideo.x11WindowId( -1 );
  124. poVideo = Arts::VideoPlayObject::null();
  125. }
  126. setBackgroundMode( PaletteBackground );
  127. repaint();
  128. // Resize GUI
  129. videoWidth = 0;
  130. videoHeight = 0;
  131. if (isHalfSize() || isNormalSize() || isDoubleSize())
  132. emit adaptSize( 0, 0 );
  133. enable = false;
  134. updateGeometry();
  135. }
  136. else
  137. {
  138. if (isEmbedded())
  139. {
  140. poVideo.x11WindowId( -1 );
  141. }
  142. poVideo = vpo;
  143. // Don't reset fullscreen mode for video playlists
  144. if (fullscreenWidget)
  145. {
  146. poVideo.x11WindowId( fullscreenWidget->winId() );
  147. fullscreenWidget->setBackgroundMode( NoBackground );
  148. setEraseColor( black );
  149. }
  150. else
  151. {
  152. poVideo.x11WindowId( winId() );
  153. setBackgroundMode( NoBackground );
  154. }
  155. enable = true;
  156. }
  157. action("double_size")->setEnabled(enable);
  158. action("half_size")->setEnabled(enable);
  159. action("normal_size")->setEnabled(enable);
  160. action("fullscreen_mode")->setEnabled(enable);
  161. }
  162. TQImage KVideoWidget::snapshot( Arts::VideoPlayObject vpo )
  163. {
  164. #if defined Q_WS_X11 && ! defined K_WS_QTONLY
  165. Window root;
  166. Pixmap pixmap;
  167. XImage *xImage;
  168. unsigned int width, height, border, depth;
  169. int x, y;
  170. if (vpo.isNull() || (long)(pixmap = vpo.x11Snapshot()) == -1)
  171. return TQImage();
  172. // Get 32bit RGBA image data (stored in 1bpp pixmap)
  173. XGetGeometry( tqt_xdisplay(), pixmap, &root, &x, &y, &width, &height, &border, &depth );
  174. xImage = XGetImage( tqt_xdisplay(), pixmap, 0, 0, width, height, 1, XYPixmap );
  175. if (xImage == 0)
  176. {
  177. XFreePixmap( tqt_xdisplay(), pixmap );
  178. return TQImage();
  179. }
  180. // Convert 32bit RGBA image data into Qt image
  181. TQImage qImage = TQImage( (uchar *)xImage->data, width/32, height, 32, (QRgb *)0, 0, TQImage::IgnoreEndian ).copy();
  182. // Free X11 resources and return Qt image
  183. XDestroyImage( xImage );
  184. XFreePixmap( tqt_xdisplay(), pixmap );
  185. return qImage;
  186. #else
  187. return 0;
  188. #endif
  189. }
  190. bool KVideoWidget::isEmbedded()
  191. {
  192. return !poVideo.isNull();
  193. }
  194. bool KVideoWidget::isFullscreen()
  195. {
  196. return ((TDEToggleAction *)action( "fullscreen_mode" ))->isChecked();
  197. }
  198. bool KVideoWidget::isHalfSize()
  199. {
  200. return ((TDEToggleAction *)action( "half_size" ))->isChecked();
  201. }
  202. bool KVideoWidget::isNormalSize()
  203. {
  204. return ((TDEToggleAction *)action( "normal_size" ))->isChecked();
  205. }
  206. bool KVideoWidget::isDoubleSize()
  207. {
  208. return ((TDEToggleAction *)action( "double_size" ))->isChecked();
  209. }
  210. void KVideoWidget::setFullscreen()
  211. {
  212. if (!isFullscreen())
  213. {
  214. ((TDEToggleAction *)action( "fullscreen_mode" ))->setChecked( true );
  215. fullscreenActivated();
  216. }
  217. }
  218. void KVideoWidget::setWindowed()
  219. {
  220. if (isFullscreen())
  221. {
  222. ((TDEToggleAction *)action( "fullscreen_mode" ))->setChecked( false );
  223. fullscreenActivated();
  224. }
  225. }
  226. void KVideoWidget::setHalfSize()
  227. {
  228. ((TDEToggleAction *)action( "half_size" ))->setChecked( true );
  229. halfSizeActivated();
  230. }
  231. void KVideoWidget::setNormalSize()
  232. {
  233. ((TDEToggleAction *)action( "normal_size" ))->setChecked( true );
  234. normalSizeActivated();
  235. }
  236. void KVideoWidget::setDoubleSize()
  237. {
  238. ((TDEToggleAction *)action( "double_size" ))->setChecked( true );
  239. doubleSizeActivated();
  240. }
  241. TQSize KVideoWidget::sizeHint() const
  242. {
  243. return TQSize( videoWidth, videoHeight );
  244. }
  245. int KVideoWidget::heightForWidth( int w ) const
  246. {
  247. if(videoWidth == 0)
  248. return 0;
  249. else
  250. return int( double(w)*double(videoHeight)/double(videoWidth) );
  251. }
  252. void KVideoWidget::mousePressEvent( TQMouseEvent *event )
  253. {
  254. TQPoint pos = mapToGlobal( event->pos() );
  255. emit mouseButtonPressed( event->button(), pos, event->state() );
  256. // ### Remove in KDE4
  257. if ( event->button() == Qt::RightButton )
  258. emit rightButtonPressed( pos );
  259. }
  260. void KVideoWidget::mouseDoubleClickEvent( TQMouseEvent *event )
  261. {
  262. emit mouseButtonDoubleClick( mapToGlobal( event->pos() ), event->state() );
  263. }
  264. void KVideoWidget::resizeEvent( TQResizeEvent *event )
  265. {
  266. TQWidget::resizeEvent( event );
  267. if (width() > minimumWidth() || height() > minimumHeight())
  268. {
  269. if (width() == QMAX( (videoWidth / 2), minimumWidth() ) &&
  270. height() == QMAX( (videoHeight / 2), minimumHeight() ))
  271. ((TDEToggleAction *)action( "half_size" ))->setChecked( true );
  272. else if (width() == QMAX( videoWidth, minimumWidth() ) &&
  273. height() == QMAX( videoHeight, minimumHeight() ))
  274. ((TDEToggleAction *)action( "normal_size" ))->setChecked( true );
  275. else if (width() == QMAX( (2 * videoWidth), minimumWidth() ) &&
  276. height() == QMAX( (2 * videoHeight), minimumHeight() ))
  277. ((TDEToggleAction *)action( "double_size" ))->setChecked( true );
  278. else
  279. {
  280. ((TDEToggleAction *)action( "half_size" ))->setChecked( false );
  281. ((TDEToggleAction *)action( "normal_size" ))->setChecked( false );
  282. ((TDEToggleAction *)action( "double_size" ))->setChecked( false );
  283. }
  284. }
  285. }
  286. void KVideoWidget::resizeNotify( int width, int height )
  287. {
  288. if(!isEmbedded()) return;
  289. videoWidth = width;
  290. videoHeight = height;
  291. if (isHalfSize())
  292. emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
  293. else if (isNormalSize())
  294. emit adaptSize( videoWidth, videoHeight );
  295. else if (isDoubleSize())
  296. emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
  297. updateGeometry();
  298. }
  299. bool KVideoWidget::x11Event( XEvent *event )
  300. {
  301. #if defined Q_WS_X11 && ! defined K_WS_QTONLY
  302. if (event->type == ClientMessage &&
  303. event->xclient.message_type ==
  304. XInternAtom( tqt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
  305. {
  306. resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
  307. }
  308. #endif
  309. return false;
  310. }
  311. void KVideoWidget::fullscreenActivated()
  312. {
  313. if (isFullscreen() == (fullscreenWidget != 0))
  314. return;
  315. if (isFullscreen())
  316. {
  317. fullscreenWidget = new KFullscreenVideoWidget( this );
  318. // Interconnect mouse button signals
  319. connect( fullscreenWidget, TQT_SIGNAL(mouseButtonPressed( int, const TQPoint &, int )),
  320. this, TQT_SIGNAL(mouseButtonPressed( int, const TQPoint &, int)) );
  321. connect( fullscreenWidget, TQT_SIGNAL(mouseButtonDoubleClick( const TQPoint &, int )),
  322. this, TQT_SIGNAL(mouseButtonDoubleClick( const TQPoint &, int )) );
  323. // ### Remove in KDE4
  324. connect( fullscreenWidget, TQT_SIGNAL(rightButtonPressed(const TQPoint &)),
  325. this, TQT_SIGNAL(rightButtonPressed(const TQPoint &)) );
  326. // Leave fullscreen mode with <Escape> key
  327. TQAccel *a = new TQAccel( fullscreenWidget );
  328. a->connectItem( a->insertItem( Key_Escape ),
  329. this, TQT_SLOT(setWindowed()) );
  330. fullscreenWidget->setFocus();
  331. fullscreenWidget->showFullScreen();
  332. if (isEmbedded())
  333. {
  334. poVideo.x11WindowId( fullscreenWidget->winId() );
  335. fullscreenWidget->setBackgroundMode( NoBackground );
  336. }
  337. }
  338. else
  339. {
  340. if (isEmbedded())
  341. {
  342. poVideo.x11WindowId( winId() );
  343. setBackgroundMode( NoBackground );
  344. }
  345. delete fullscreenWidget;
  346. fullscreenWidget = 0;
  347. }
  348. }
  349. void KVideoWidget::halfSizeActivated()
  350. {
  351. if (isHalfSize())
  352. {
  353. if(isEmbedded()) emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
  354. setWindowed();
  355. }
  356. }
  357. void KVideoWidget::normalSizeActivated()
  358. {
  359. if (isNormalSize())
  360. {
  361. if(isEmbedded()) emit adaptSize( videoWidth, videoHeight );
  362. setWindowed();
  363. }
  364. }
  365. void KVideoWidget::doubleSizeActivated()
  366. {
  367. if (isDoubleSize())
  368. {
  369. if(isEmbedded()) emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
  370. setWindowed();
  371. }
  372. }
  373. #include "kvideowidget.moc"