~ubuntu-branches/ubuntu/oneiric/phonon/oneiric-201108111512

« back to all changes in this revision

Viewing changes to xine/videowidget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2011-01-24 10:12:11 UTC
  • mfrom: (0.5.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110124101211-w9rew7q0dmwbwhqx
Tags: 4:4.7.0really4.4.4-0ubuntu1
* New upstream release
* Xine and GStreamer backends now split out source, remove build-deps and
  binary packages from debian/control
* Remove 02_no_rpath.patch, now upstream
* Disable kubuntu04_no_va_mangle.patch, no longer applies
* Remove kubuntu_05_gst_codec_installer_window_id.diff, kubuntu_06_forward_events.diff,
  kubuntu_07_include_fix.diff, gstreamer now separate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  This file is part of the KDE project
2
 
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
3
 
 
4
 
    This program is free software; you can redistribute it and/or
5
 
    modify it under the terms of the GNU Library General Public
6
 
    License as published by the Free Software Foundation; either
7
 
    version 2 of the License, or (at your option) any later version.
8
 
 
9
 
    This library is distributed in the hope that it will be useful,
10
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
    Library General Public License for more details.
13
 
 
14
 
    You should have received a copy of the GNU Library General Public License
15
 
    along with this library; see the file COPYING.LIB.  If not, write to
16
 
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 
    Boston, MA 02110-1301, USA.
18
 
 
19
 
*/
20
 
#include "videowidget.h"
21
 
#include "events.h"
22
 
#include <QPalette>
23
 
#include <QtCore/QExplicitlySharedDataPointer>
24
 
#include <QtCore/QMutexLocker>
25
 
#include <QtCore/QSharedData>
26
 
#include <QImage>
27
 
#include <QPainter>
28
 
 
29
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
30
 
#include <QX11Info>
31
 
#include <xcb/xcb.h>
32
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
33
 
 
34
 
#include "backend.h"
35
 
#include "xineengine.h"
36
 
#include "mediaobject.h"
37
 
 
38
 
#include <QApplication>
39
 
#include <QDesktopWidget>
40
 
#include <QMouseEvent>
41
 
#include <QVBoxLayout>
42
 
#include "keepreference.h"
43
 
 
44
 
namespace Phonon
45
 
{
46
 
namespace Xine
47
 
{
48
 
 
49
 
static XcbConnection *s_instance = 0;
50
 
 
51
 
QExplicitlySharedDataPointer<XcbConnection> XcbConnection::instance()
52
 
{
53
 
    debug() << Q_FUNC_INFO;
54
 
    if (!s_instance) {
55
 
        new XcbConnection;
56
 
    }
57
 
    Q_ASSERT(s_instance);
58
 
    return QExplicitlySharedDataPointer<XcbConnection>(s_instance);
59
 
}
60
 
 
61
 
XcbConnection::~XcbConnection()
62
 
{
63
 
    debug() << Q_FUNC_INFO;
64
 
    s_instance = 0;
65
 
 
66
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
67
 
    xcb_disconnect(m_xcbConnection);
68
 
    m_xcbConnection = 0;
69
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
70
 
}
71
 
 
72
 
XcbConnection::XcbConnection()
73
 
    : m_screen(0)
74
 
{
75
 
    debug() << Q_FUNC_INFO;
76
 
    Q_ASSERT(!s_instance);
77
 
    s_instance = this;
78
 
    int preferredScreen = 0;
79
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
80
 
    m_xcbConnection = xcb_connect(NULL, &preferredScreen);//DisplayString(x11Info().display()), NULL);
81
 
    if (m_xcbConnection) {
82
 
        xcb_screen_iterator_t screenIt = xcb_setup_roots_iterator(xcb_get_setup(m_xcbConnection));
83
 
        while ((screenIt.rem > 1) && (preferredScreen > 0)) {
84
 
            xcb_screen_next(&screenIt);
85
 
            --preferredScreen;
86
 
        }
87
 
        m_screen = screenIt.data;
88
 
    }
89
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
90
 
}
91
 
 
92
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
93
 
static void dest_size_cb(void *user_data, int video_width, int video_height, double video_pixel_aspect,
94
 
        int *dest_width, int *dest_height, double *dest_pixel_aspect)
95
 
{
96
 
    Phonon::Xine::VideoWidgetXT *xt = static_cast<VideoWidgetXT *>(user_data);
97
 
    if (!xt->videoWidget()) {
98
 
        *dest_width = 1;
99
 
        *dest_height = 1;
100
 
        *dest_pixel_aspect = 1.0;
101
 
        return;
102
 
    }
103
 
 
104
 
    int win_x, win_y;
105
 
    xt->videoWidget()->xineCallback(win_x, win_y, *dest_width, *dest_height, *dest_pixel_aspect,
106
 
            video_width, video_height, video_pixel_aspect, false);
107
 
}
108
 
 
109
 
static void frame_output_cb(void *user_data, int video_width, int video_height,
110
 
        double video_pixel_aspect, int *dest_x, int *dest_y,
111
 
        int *dest_width, int *dest_height,
112
 
        double *dest_pixel_aspect, int *win_x, int *win_y)
113
 
{
114
 
    Phonon::Xine::VideoWidgetXT *xt = static_cast<VideoWidgetXT *>(user_data);
115
 
    if (!xt->videoWidget()) {
116
 
        *win_x = 0;
117
 
        *win_y = 0;
118
 
        *dest_width = 1;
119
 
        *dest_height = 1;
120
 
        *dest_pixel_aspect = 1.0;
121
 
        return;
122
 
    }
123
 
 
124
 
    xt->videoWidget()->xineCallback(*win_x, *win_y, *dest_width, *dest_height, *dest_pixel_aspect,
125
 
            video_width, video_height, video_pixel_aspect, true);
126
 
 
127
 
    *dest_x = 0;
128
 
    *dest_y = 0;
129
 
}
130
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
131
 
 
132
 
void VideoWidget::xineCallback(int &x, int &y, int &width, int &height, double &ratio,
133
 
        int videoWidth, int videoHeight, double videoRatio, bool mayResize)
134
 
{
135
 
    Q_UNUSED(videoRatio);
136
 
    Q_UNUSED(videoWidth);
137
 
    Q_UNUSED(videoHeight);
138
 
    Q_UNUSED(mayResize);
139
 
 
140
 
    x = this->x();
141
 
    y = this->y();
142
 
    width = this->width();
143
 
    height = this->height();
144
 
 
145
 
    // square pixels
146
 
    ratio = 1.0;
147
 
}
148
 
 
149
 
VideoWidgetXT::VideoWidgetXT(VideoWidget *w)
150
 
    : SinkNodeXT("VideoWidget"),
151
 
    m_xcbConnection(0), //XcbConnection::instance()),
152
 
    m_videoPort(0), m_videoWidget(w), m_isValid(false)
153
 
{
154
 
    memset(&m_visual, 0, sizeof(m_visual));
155
 
    Q_ASSERT(!m_xine);
156
 
    m_xine = Backend::xine();
157
 
}
158
 
 
159
 
void VideoWidgetXT::createVideoPort()
160
 
{
161
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
162
 
    Q_ASSERT(!m_videoPort);
163
 
    int preferredScreen = 0;
164
 
    m_xcbConnection = xcb_connect(NULL, &preferredScreen);//DisplayString(x11Info().display()), NULL);
165
 
    debug() << Q_FUNC_INFO << "xcb_connect" << m_xcbConnection;
166
 
    if (m_xcbConnection && m_xine) {
167
 
        xcb_screen_iterator_t screenIt = xcb_setup_roots_iterator(xcb_get_setup(m_xcbConnection));
168
 
        while ((screenIt.rem > 1) && (preferredScreen > 0)) {
169
 
            xcb_screen_next(&screenIt);
170
 
            --preferredScreen;
171
 
        }
172
 
        m_visual.connection = m_xcbConnection;
173
 
        //Q_ASSERT(m_xcbConnection->screen());
174
 
        //m_visual.screen = m_xcbConnection->screen();
175
 
        m_visual.screen = screenIt.data;
176
 
        m_visual.window = m_videoWidget->winId();
177
 
        m_visual.user_data = static_cast<void *>(this);
178
 
        m_visual.dest_size_cb = Phonon::Xine::dest_size_cb;
179
 
        m_visual.frame_output_cb = Phonon::Xine::frame_output_cb;
180
 
 
181
 
        // make sure all Qt<->X communication is done, else xine_open_video_driver will crash
182
 
        QApplication::syncX();
183
 
 
184
 
        Q_ASSERT(m_videoWidget->testAttribute(Qt::WA_WState_Created));
185
 
        m_videoPort = xine_open_video_driver(m_xine, "auto", XINE_VISUAL_TYPE_XCB, static_cast<void *>(&m_visual));
186
 
        if (!m_videoPort) {
187
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
188
 
            m_videoPort = xine_open_video_driver(m_xine, "auto", XINE_VISUAL_TYPE_NONE, 0);
189
 
            qWarning() << "No xine video output plugin using libxcb for threadsafe access to the X server found. No video for you.";
190
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
191
 
        }
192
 
    }
193
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
194
 
}
195
 
 
196
 
VideoWidget::VideoWidget(QWidget *parent)
197
 
    : QWidget(parent),
198
 
    SinkNode(new VideoWidgetXT(this)),
199
 
    m_aspectRatio(Phonon::VideoWidget::AspectRatioAuto),
200
 
    m_scaleMode(Phonon::VideoWidget::FitInView),
201
 
    m_empty(true),
202
 
    m_brightness(0.0),
203
 
    m_contrast(0.0),
204
 
    m_hue(0.0),
205
 
    m_saturation(0.0)
206
 
{
207
 
    // for some reason it can hang if the widget is 0x0
208
 
    setMinimumSize(1, 1);
209
 
 
210
 
    QPalette palette = this->palette();
211
 
    palette.setColor(backgroundRole(), Qt::black);
212
 
    setPalette(palette);
213
 
 
214
 
    // when resizing fill with black (backgroundRole color) the rest is done by paintEvent
215
 
    setAttribute(Qt::WA_OpaquePaintEvent, true);
216
 
 
217
 
    // disable Qt composition management as Xine draws onto the widget directly using X calls
218
 
    setAttribute(Qt::WA_PaintOnScreen, true);
219
 
 
220
 
    K_XT(VideoWidget);
221
 
    xt->createVideoPort();
222
 
 
223
 
    // required for dvdnav
224
 
    setMouseTracking(true);
225
 
}
226
 
 
227
 
VideoWidget::~VideoWidget()
228
 
{
229
 
    debug() << Q_FUNC_INFO;
230
 
    K_XT(VideoWidget);
231
 
    xt->m_videoWidget = 0;
232
 
    if (xt->m_videoPort) {
233
 
        xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_WILL_DESTROY_DRAWABLE, 0);
234
 
    }
235
 
}
236
 
 
237
 
VideoWidgetXT::~VideoWidgetXT()
238
 
{
239
 
    debug() << Q_FUNC_INFO;
240
 
    if (m_videoPort && m_xine) {
241
 
        xine_close_video_driver(m_xine, m_videoPort);
242
 
    }
243
 
    if (m_xcbConnection) {
244
 
        debug() << Q_FUNC_INFO << "xcb_disconnect" << m_xcbConnection;
245
 
        xcb_disconnect(m_xcbConnection);
246
 
        m_xcbConnection = 0;
247
 
    }
248
 
}
249
 
 
250
 
Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const
251
 
{
252
 
    return m_aspectRatio;
253
 
}
254
 
 
255
 
void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio)
256
 
{
257
 
    m_aspectRatio = aspectRatio;
258
 
    switch (m_aspectRatio) {
259
 
    case Phonon::VideoWidget::AspectRatioWidget:
260
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_SQUARE));
261
 
        break;
262
 
    case Phonon::VideoWidget::AspectRatioAuto:
263
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO));
264
 
        break;
265
 
    case Phonon::VideoWidget::AspectRatio4_3:
266
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3));
267
 
        break;
268
 
    case Phonon::VideoWidget::AspectRatio16_9:
269
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC));
270
 
        break;
271
 
    }
272
 
    updateZoom();
273
 
}
274
 
 
275
 
Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const
276
 
{
277
 
    return m_scaleMode;
278
 
}
279
 
 
280
 
void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode mode)
281
 
{
282
 
    m_scaleMode = mode;
283
 
    updateZoom();
284
 
}
285
 
 
286
 
qreal VideoWidget::brightness() const
287
 
{
288
 
    return m_brightness;
289
 
}
290
 
 
291
 
static const qreal ONE = 1.0;
292
 
void VideoWidget::setBrightness(qreal newBrightness)
293
 
{
294
 
    newBrightness = qBound(-ONE, newBrightness, ONE);
295
 
    if (m_brightness != newBrightness) {
296
 
        m_brightness = newBrightness;
297
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_BRIGHTNESS, static_cast<int>(0x7fff * (m_brightness + ONE))));
298
 
    }
299
 
}
300
 
 
301
 
qreal VideoWidget::contrast() const
302
 
{
303
 
    return m_contrast;
304
 
}
305
 
 
306
 
void VideoWidget::setContrast(qreal newContrast)
307
 
{
308
 
    newContrast = qBound(-ONE, newContrast, ONE);
309
 
    if (m_contrast != newContrast) {
310
 
        m_contrast = newContrast;
311
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_CONTRAST, static_cast<int>(0x7fff * (m_contrast + ONE))));
312
 
    }
313
 
}
314
 
 
315
 
qreal VideoWidget::hue() const
316
 
{
317
 
    return m_hue;
318
 
}
319
 
 
320
 
void VideoWidget::setHue(qreal newHue)
321
 
{
322
 
    newHue = qBound(-ONE, newHue, ONE);
323
 
    if (m_hue != newHue) {
324
 
        m_hue = newHue;
325
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_HUE, static_cast<int>(0x7fff * (m_hue + ONE))));
326
 
    }
327
 
}
328
 
 
329
 
qreal VideoWidget::saturation() const
330
 
{
331
 
    return m_saturation;
332
 
}
333
 
 
334
 
void VideoWidget::setSaturation(qreal newSaturation)
335
 
{
336
 
    newSaturation = qBound(-ONE, newSaturation, ONE);
337
 
    if (m_saturation != newSaturation) {
338
 
        m_saturation = newSaturation;
339
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_SATURATION, static_cast<int>(0x7fff * (m_saturation + ONE))));
340
 
    }
341
 
}
342
 
 
343
 
QImage VideoWidget::snapshot() const
344
 
{
345
 
    QImage img;
346
 
    QMutexLocker lock(&m_snapshotLock);
347
 
    const_cast<VideoWidget *>(this)->upstreamEvent(new RequestSnapshotEvent(img, &m_snapshotWait) );
348
 
    if (m_snapshotWait.wait(&m_snapshotLock, 1000)) {
349
 
      return img;
350
 
    }
351
 
    return QImage();
352
 
}
353
 
 
354
 
/*
355
 
int VideoWidget::overlayCapabilities() const
356
 
{
357
 
    return Phonon::Experimental::OverlayApi::OverlayOpaque;
358
 
}
359
 
 
360
 
bool VideoWidget::createOverlay(QWidget *widget, int type)
361
 
{
362
 
    if ((overlay != 0) || (type != Phonon::Experimental::OverlayApi::OverlayOpaque))
363
 
        return false;
364
 
 
365
 
    if (layout() == 0) {
366
 
        QLayout *layout = new QVBoxLayout(this);
367
 
        layout->setMargin(0);
368
 
        setLayout(layout);
369
 
    }
370
 
 
371
 
    layout()->addWidget(widget);
372
 
    overlay = widget;
373
 
 
374
 
    return true;
375
 
}
376
 
 
377
 
void VideoWidget::childEvent(QChildEvent *event)
378
 
{
379
 
    if (event->removed() && (event->child() == overlay))
380
 
        overlay = 0;
381
 
    QWidget::childEvent(event);
382
 
}
383
 
*/
384
 
 
385
 
void VideoWidget::updateZoom()
386
 
{
387
 
    if (m_aspectRatio == Phonon::VideoWidget::AspectRatioWidget) {
388
 
        const QSize s = size();
389
 
        QSize imageSize = m_sizeHint;
390
 
        imageSize.scale(s, Qt::KeepAspectRatio);
391
 
        if (imageSize.width() < s.width()) {
392
 
            const int zoom = s.width() * 100 / imageSize.width();
393
 
            upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_X, zoom));
394
 
            upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_Y, 100));
395
 
        } else {
396
 
            const int zoom = s.height() * 100 / imageSize.height();
397
 
            upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_X, 100));
398
 
            upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_Y, zoom));
399
 
        }
400
 
    } else if (m_scaleMode == Phonon::VideoWidget::ScaleAndCrop) {
401
 
        const QSize s = size();
402
 
        QSize imageSize = m_sizeHint;
403
 
        // the image size is in square pixels
404
 
        // first transform it to the current aspect ratio
405
 
        debug() << Q_FUNC_INFO << imageSize;
406
 
        switch (m_aspectRatio) {
407
 
        case Phonon::VideoWidget::AspectRatioAuto:
408
 
            // FIXME: how can we find out the ratio xine decided on? the event?
409
 
            break;
410
 
        case Phonon::VideoWidget::AspectRatio4_3:
411
 
            imageSize.setWidth(imageSize.height() * 4 / 3);
412
 
            break;
413
 
        case Phonon::VideoWidget::AspectRatio16_9:
414
 
            imageSize.setWidth(imageSize.height() * 16 / 9);
415
 
            break;
416
 
        default:
417
 
            // correct ratio already
418
 
            break;
419
 
        }
420
 
        debug() << Q_FUNC_INFO << imageSize;
421
 
        imageSize.scale(s, Qt::KeepAspectRatioByExpanding);
422
 
        debug() << Q_FUNC_INFO << imageSize << s;
423
 
        int zoom;
424
 
        if (imageSize.width() > s.width()) {
425
 
            zoom = imageSize.width() * 100 / s.width();
426
 
        } else {
427
 
            zoom = imageSize.height() * 100 / s.height();
428
 
        }
429
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_X, zoom));
430
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_Y, zoom));
431
 
    } else {
432
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_X, 100));
433
 
        upstreamEvent(new SetParamEvent(XINE_PARAM_VO_ZOOM_Y, 100));
434
 
    }
435
 
}
436
 
 
437
 
void VideoWidget::resizeEvent(QResizeEvent *ev)
438
 
{
439
 
    updateZoom();
440
 
    QWidget::resizeEvent(ev);
441
 
}
442
 
 
443
 
bool VideoWidget::event(QEvent *ev)
444
 
{
445
 
    switch (ev->type()) {
446
 
    case Event::NavButtonIn:
447
 
        debug() << Q_FUNC_INFO << "NavButtonIn";
448
 
        setCursor(QCursor(Qt::PointingHandCursor));
449
 
        ev->accept();
450
 
        return true;
451
 
    case Event::NavButtonOut:
452
 
        debug() << Q_FUNC_INFO << "NavButtonOut";
453
 
        unsetCursor();
454
 
        ev->accept();
455
 
        return true;
456
 
    case Event::FrameFormatChange:
457
 
        ev->accept();
458
 
        {
459
 
            FrameFormatChangeEvent *e = static_cast<FrameFormatChangeEvent *>(ev);
460
 
            debug() << Q_FUNC_INFO << "FrameFormatChangeEvent " << e->size;
461
 
            m_sizeHint = e->size;
462
 
            updateGeometry();
463
 
        }
464
 
        return true;
465
 
    default:
466
 
        return QWidget::event(ev);
467
 
    }
468
 
}
469
 
 
470
 
void VideoWidget::mouseMoveEvent(QMouseEvent *mev)
471
 
{
472
 
    K_XT(VideoWidget);
473
 
 
474
 
    x11_rectangle_t   rect;
475
 
    xine_event_t      *event = new xine_event_t;
476
 
    xine_input_data_t *input = new xine_input_data_t;
477
 
 
478
 
    rect.x = mev->x();
479
 
    rect.y = mev->y();
480
 
    rect.w = 0;
481
 
    rect.h = 0;
482
 
 
483
 
    xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void *) &rect);
484
 
 
485
 
    event->type        = XINE_EVENT_INPUT_MOUSE_MOVE;
486
 
    event->data        = input;
487
 
    event->data_length = sizeof(*input);
488
 
    input->button      = 0;
489
 
    input->x           = rect.x;
490
 
    input->y           = rect.y;
491
 
    //debug() << Q_FUNC_INFO << "upstreamEvent(EventSendEvent(move " << rect.x << rect.y;
492
 
    upstreamEvent(new EventSendEvent(event));
493
 
 
494
 
    QWidget::mouseMoveEvent(mev);
495
 
}
496
 
 
497
 
void VideoWidget::mousePressEvent(QMouseEvent *mev)
498
 
{
499
 
    K_XT(VideoWidget);
500
 
 
501
 
    uint8_t button = 1;
502
 
    switch (mev->button()) {
503
 
    case Qt::NoButton:
504
 
    case Qt::XButton1:
505
 
    case Qt::XButton2:
506
 
    case Qt::MouseButtonMask:
507
 
        break;
508
 
    case Qt::RightButton: // 3
509
 
        ++button;
510
 
    case Qt::MidButton: // 2
511
 
        ++button;
512
 
    case Qt::LeftButton: // 1
513
 
        {
514
 
            x11_rectangle_t   rect;
515
 
            xine_event_t      *event = new xine_event_t;
516
 
            xine_input_data_t *input = new xine_input_data_t;
517
 
 
518
 
            rect.x = mev->x();
519
 
            rect.y = mev->y();
520
 
            rect.w = 0;
521
 
            rect.h = 0;
522
 
 
523
 
            xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void *) &rect);
524
 
 
525
 
            event->type        = XINE_EVENT_INPUT_MOUSE_BUTTON;
526
 
            event->data        = input;
527
 
            event->data_length = sizeof(*input);
528
 
            input->button      = button;
529
 
            input->x           = rect.x;
530
 
            input->y           = rect.y;
531
 
            //debug() << Q_FUNC_INFO << "upstreamEvent(EventSendEvent(button " << rect.x << rect.y;
532
 
            upstreamEvent(new EventSendEvent(event));
533
 
        }
534
 
    }
535
 
    QWidget::mousePressEvent(mev);
536
 
}
537
 
 
538
 
bool VideoWidget::isValid() const
539
 
{
540
 
    return true;
541
 
    //K_XT(const VideoWidget);
542
 
    //return xt->m_isValid;
543
 
}
544
 
 
545
 
xine_video_port_t *VideoWidgetXT::videoPort() const
546
 
{
547
 
    return m_videoPort;
548
 
}
549
 
 
550
 
void VideoWidgetXT::rewireTo(SourceNodeXT *source)
551
 
{
552
 
    if (!source->videoOutputPort()) {
553
 
        return;
554
 
    }
555
 
    xine_post_wire_video_port(source->videoOutputPort(), videoPort());
556
 
}
557
 
 
558
 
void VideoWidget::paintEvent(QPaintEvent *event)
559
 
{
560
 
    K_XT(VideoWidget);
561
 
 
562
 
    //debug() << Q_FUNC_INFO << "m_empty = " << m_empty;
563
 
    if (m_empty || !source()) {// || m_path->mediaObject()->state() == Phonon::LoadingState) {
564
 
        QPainter p(this);
565
 
        p.fillRect(rect(), Qt::black);
566
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
567
 
    } else if (xt->m_videoPort) {
568
 
        //debug() << Q_FUNC_INFO;
569
 
        const QRect &rect = event->rect();
570
 
 
571
 
        xcb_expose_event_t xcb_event;
572
 
        memset(&xcb_event, 0, sizeof(xcb_event));
573
 
 
574
 
        xcb_event.window = winId();
575
 
        xcb_event.x = rect.x();
576
 
        xcb_event.y = rect.y();
577
 
        xcb_event.width = rect.width();
578
 
        xcb_event.height = rect.height();
579
 
        xcb_event.count = 0;
580
 
 
581
 
        xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_EXPOSE_EVENT, &xcb_event);
582
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
583
 
    } else {
584
 
        QPainter p(this);
585
 
        p.fillRect(rect(), Qt::black);
586
 
    }
587
 
    QWidget::paintEvent(event);
588
 
}
589
 
 
590
 
void VideoWidget::showEvent(QShowEvent *)
591
 
{
592
 
    //K_XT(VideoWidget);
593
 
    //xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_VIDEOWIN_VISIBLE, static_cast<void *>(1));
594
 
}
595
 
 
596
 
void VideoWidget::hideEvent(QHideEvent *)
597
 
{
598
 
    //K_XT(VideoWidget);
599
 
    //xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_VIDEOWIN_VISIBLE, static_cast<void *>(0));
600
 
}
601
 
 
602
 
void VideoWidget::changeEvent(QEvent *event)
603
 
{
604
 
    K_XT(VideoWidget);
605
 
 
606
 
    if (event->type() == QEvent::ParentAboutToChange)
607
 
    {
608
 
        debug() << Q_FUNC_INFO << "ParentAboutToChange";
609
 
    }
610
 
    else if (event->type() == QEvent::ParentChange)
611
 
    {
612
 
        debug() << Q_FUNC_INFO << "ParentChange" << winId();
613
 
//#ifndef PHONON_XINE_NO_VIDEOWIDGET
614
 
        if (xt->m_visual.window != winId()) {
615
 
            xt->m_visual.window = winId();
616
 
            if (xt->m_videoPort) {
617
 
                // make sure all Qt<->X communication is done, else winId() might not be known at the
618
 
                // X-server yet
619
 
                QApplication::syncX();
620
 
                xine_port_send_gui_data(xt->m_videoPort, XINE_GUI_SEND_DRAWABLE_CHANGED, reinterpret_cast<void *>(xt->m_visual.window));
621
 
                debug() << Q_FUNC_INFO << "XINE_GUI_SEND_DRAWABLE_CHANGED done.";
622
 
            }
623
 
        }
624
 
//#endif // PHONON_XINE_NO_VIDEOWIDGET
625
 
    }
626
 
}
627
 
 
628
 
void VideoWidget::downstreamEvent(Event *e)
629
 
{
630
 
    Q_ASSERT(e);
631
 
    switch (e->type()) {
632
 
    case Event::HasVideo:
633
 
        {
634
 
            HasVideoEvent *ev = static_cast<HasVideoEvent *>(e);
635
 
            m_empty = !ev->hasVideo;
636
 
            if (m_empty) {
637
 
                update();
638
 
            }
639
 
        }
640
 
        break;
641
 
    default:
642
 
        QCoreApplication::sendEvent(this, e);
643
 
        break;
644
 
    }
645
 
    SinkNode::downstreamEvent(e);
646
 
}
647
 
 
648
 
void VideoWidget::aboutToChangeXineEngine()
649
 
{
650
 
    debug() << Q_FUNC_INFO;
651
 
    K_XT(VideoWidget);
652
 
    if (xt->m_videoPort) {
653
 
        VideoWidgetXT *xt2 = new VideoWidgetXT(this);
654
 
        xt2->m_xine = xt->m_xine;
655
 
        xt2->m_videoPort = xt->m_videoPort;
656
 
        xt2->m_xcbConnection = xt->m_xcbConnection;
657
 
        xt->m_videoPort = 0;
658
 
        xt->m_xcbConnection = 0;
659
 
        KeepReference<> *keep = new KeepReference<>;
660
 
        keep->addObject(xt2);
661
 
        keep->ready();
662
 
    }
663
 
}
664
 
 
665
 
void VideoWidget::xineEngineChanged()
666
 
{
667
 
    debug() << Q_FUNC_INFO;
668
 
    K_XT(VideoWidget);
669
 
    if (xt->m_xine) {
670
 
        Q_ASSERT(!xt->m_videoPort);
671
 
        xt->createVideoPort();
672
 
    }
673
 
}
674
 
 
675
 
}} //namespace Phonon::Xine
676
 
 
677
 
#include "videowidget.moc"
678
 
// vim: sw=4 ts=4