File indexing completed on 2024-04-21 15:38:31
0001 /* This file is part of the KMPlayer application 0002 Copyright (C) 2004 Koos Vriezen <koos.vriezen@xs4all.nl> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include <stdio.h> 0021 #include <string.h> 0022 #include <math.h> 0023 #include "config-kmplayer.h" 0024 #include <dcopclient.h> 0025 #include <qcstring.h> 0026 #include <qtimer.h> 0027 #include <qfile.h> 0028 #include <qurl.h> 0029 #include <qthread.h> 0030 #include <qmutex.h> 0031 #include <qdom.h> 0032 #include "kmplayer_backend.h" 0033 #include "kmplayer_callback_stub.h" 0034 #include "kmplayer_callback.h" 0035 #include "xvplayer.h" 0036 #include <X11/X.h> 0037 #include <X11/Xlib.h> 0038 #include <X11/Xutil.h> 0039 #include <X11/keysym.h> 0040 #include <X11/Xatom.h> 0041 #include <X11/Xutil.h> 0042 #include <X11/extensions/XShm.h> 0043 #include <X11/extensions/Xvlib.h> 0044 0045 0046 static char configfile[2048]; 0047 0048 static Display *display; 0049 static KXVideoPlayer *xvapp; 0050 static KMPlayer::Callback_stub * callback; 0051 static Window wid; 0052 static GC gc; 0053 static bool window_created = true; 0054 static bool wants_config; 0055 static bool verbose; 0056 static bool running; 0057 static bool have_freq; 0058 static bool xv_success; 0059 static bool reset_xv_autopaint_colorkey; 0060 static bool reset_xv_mute; 0061 static int xvport; 0062 static int xv_encoding = -1; 0063 static QString xv_norm; 0064 static int xv_frequency; 0065 static int screen; 0066 static int movie_width; 0067 static int movie_height; 0068 static int current_volume; 0069 static int tmp_volume; 0070 static const int start_vol_timeout = 100; 0071 static const int inc_vol_timeout = 20; 0072 Atom xv_enc_atom; 0073 Atom xv_hue_atom; 0074 Atom xv_saturation_atom; 0075 Atom xv_brightness_atom; 0076 Atom xv_contrast_atom; 0077 Atom xv_freq_atom; 0078 Atom xv_volume_atom; 0079 Atom xv_mute_atom; 0080 Atom xv_autopaint_colorkey_atom; 0081 enum { 0082 limit_volume = 0, 0083 limit_hue, limit_contrast, limit_brightness, limit_saturation, 0084 limit_last 0085 }; 0086 static struct Limit { int min; int max; } xv_limits [limit_last]; 0087 static QString elmentry ("entry"); 0088 static QString elmitem ("item"); 0089 static QString attname ("name"); 0090 static QString atttype ("type"); 0091 static QString attdefault ("DEFAULT"); 0092 static QString attvalue ("value"); 0093 //static QString attstart ("START"); 0094 //static QString attend ("END"); 0095 //static QString valrange ("range"); 0096 //static QString valnum ("num"); 0097 //static QString valbool ("bool"); 0098 //static QString valenum ("enum"); 0099 //static QString valstring ("string"); 0100 static QString valtree ("tree"); 0101 static QByteArray config_buf; 0102 0103 extern "C" { 0104 0105 } // extern "C" 0106 0107 static void putVideo () { 0108 XWindowAttributes attr; 0109 XGetWindowAttributes (display, wid, &attr); 0110 XvPutVideo (display, xvport, wid, gc, 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); 0111 } 0112 0113 using namespace KMPlayer; 0114 0115 Backend::Backend () 0116 : DCOPObject (QCString ("Backend")) { 0117 } 0118 0119 Backend::~Backend () {} 0120 0121 void Backend::setURL (unsigned long, QString) { 0122 } 0123 0124 void Backend::setSubTitleURL (unsigned long, QString) { 0125 } 0126 0127 void Backend::play (long unsigned int, int) { 0128 xvapp->play (); 0129 } 0130 0131 void Backend::stop (unsigned long) { 0132 QTimer::singleShot (0, xvapp, SLOT (stop ())); 0133 } 0134 0135 void Backend::pause (unsigned long) { 0136 } 0137 0138 void Backend::seek (unsigned long, int, bool /*absolute*/) { 0139 } 0140 0141 void Backend::hue (unsigned long, int h, bool) { 0142 if (xv_limits[limit_hue].max > xv_limits[limit_hue].min) 0143 xvapp->hue ((h + 100) * (xv_limits[limit_hue].max - xv_limits[limit_hue].min)/200 + xv_limits[limit_hue].min); 0144 } 0145 0146 void Backend::saturation (unsigned long, int s, bool) { 0147 if (xv_limits[limit_saturation].max > xv_limits[limit_saturation].min) 0148 xvapp->saturation ((s + 100) * (xv_limits[limit_saturation].max - xv_limits[limit_saturation].min)/200 + xv_limits[limit_saturation].min); 0149 } 0150 0151 void Backend::contrast (unsigned long, int c, bool) { 0152 if (xv_limits[limit_contrast].max > xv_limits[limit_contrast].min) 0153 xvapp->contrast ((c + 100)*(xv_limits[limit_contrast].max - xv_limits[limit_contrast].min)/200 + xv_limits[limit_contrast].min); 0154 } 0155 0156 void Backend::brightness (unsigned long, int b, bool) { 0157 if (xv_limits[limit_brightness].max > xv_limits[limit_brightness].min) 0158 xvapp->brightness ((b + 100)*(xv_limits[limit_brightness].max - xv_limits[limit_brightness].min)/200 + xv_limits[limit_brightness].min); 0159 } 0160 0161 void Backend::volume (unsigned long, int v, bool) { 0162 if (xv_limits[limit_volume].max > xv_limits[limit_volume].min) 0163 xvapp->volume (v*(xv_limits[limit_volume].max - xv_limits[limit_volume].min)/100 + xv_limits[limit_volume].min); 0164 } 0165 0166 void Backend::property (unsigned long wid, QString prop, QString val) { 0167 if (prop == "frequency") 0168 xvapp->frequency (val.toInt ()); 0169 } 0170 0171 void Backend::setAudioLang (unsigned long, int, QString) { 0172 } 0173 0174 void Backend::setSubtitle (unsigned long, int, QString) { 0175 } 0176 0177 void Backend::quit () { 0178 delete callback; 0179 callback = 0L; 0180 if (running) 0181 stop (0); 0182 else 0183 QTimer::singleShot (0, qApp, SLOT (quit ())); 0184 } 0185 0186 bool updateConfigEntry (const QString & name, const QString & value) { 0187 fprintf (stderr, "%s=%s\n", name.ascii (), (const char *) value.local8Bit ()); 0188 return true; 0189 } 0190 0191 void Backend::setConfig (QByteArray data) { 0192 QString err; 0193 int line, column; 0194 QDomDocument dom; 0195 if (dom.setContent (data, false, &err, &line, &column)) { 0196 if (dom.childNodes().length () == 1) { 0197 for (QDomNode node = dom.firstChild().firstChild(); 0198 !node.isNull (); 0199 node = node.nextSibling ()) { 0200 QDomNamedNodeMap attr = node.attributes (); 0201 updateConfigEntry (attr.namedItem (attname).nodeValue (), 0202 attr.namedItem (attvalue).nodeValue ()); 0203 } 0204 } else 0205 err = QString ("invalid data"); 0206 } 0207 if (callback) 0208 callback->errorMessage (0, 0, err); 0209 } 0210 0211 bool Backend::isPlaying (unsigned long) { 0212 return running; 0213 } 0214 0215 KXVideoPlayer::KXVideoPlayer (int _argc, char ** _argv) 0216 : QApplication (_argc, _argv, false), mute_timer (0) { 0217 } 0218 0219 void KXVideoPlayer::init () { 0220 int xpos = 0; 0221 int ypos = 0; 0222 int width = 320; 0223 int height = 200; 0224 0225 XLockDisplay(display); 0226 if (window_created) 0227 wid = XCreateSimpleWindow(display, XDefaultRootWindow(display), 0228 xpos, ypos, width, height, 1, 0, 0); 0229 if (!callback) 0230 QTimer::singleShot (10, this, SLOT (play ())); 0231 XSelectInput (display, wid, 0232 (PointerMotionMask | ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask)); // | SubstructureNotifyMask)); 0233 XvAdaptorInfo * ai; 0234 unsigned int adaptors; 0235 xv_success = true; 0236 QDomDocument doc; 0237 QDomElement root = doc.createElement (QString ("document")); 0238 if (XvQueryAdaptors (display, XDefaultRootWindow (display), &adaptors, &ai) == Success) { 0239 QDomElement elm = doc.createElement (elmentry); 0240 elm.setAttribute (attname, QString ("XVideo")); 0241 elm.setAttribute (atttype, valtree); 0242 for (unsigned i = 0; i < adaptors; i++) { 0243 if ((ai[i].type & XvInputMask) && 0244 (ai[i].type & XvVideoMask) && 0245 ai[i].base_id > 0) { 0246 int port = ai[i].base_id; 0247 fprintf (stderr, "xvport %d\n", port); 0248 bool freq_found = false; 0249 XvAttribute *attributes = 0L; 0250 int nr_attr, cur_val; 0251 attributes = XvQueryPortAttributes (display, port, &nr_attr); 0252 if (attributes) { 0253 for (int i = 0; i < nr_attr; i++) { 0254 if (!strcmp (attributes[i].name, "XV_FREQ")) 0255 freq_found = true; 0256 Atom atom = XInternAtom (display, attributes[i].name, false); 0257 fprintf (stderr, "%s[%d] (%d .. %d)", attributes[i].name, ( int ) atom, attributes[i].min_value, attributes[i].max_value); 0258 if ((attributes[i].flags & XvGettable) && XvGetPortAttribute (display, port, atom, &cur_val) == Success) 0259 fprintf (stderr, " current: %d", cur_val); 0260 fprintf (stderr, "\n"); 0261 } 0262 XFree(attributes); 0263 } 0264 if (!xvport && ((xv_frequency > 0) == freq_found)) { 0265 fprintf (stderr, "using xvport %d\n", port); 0266 xvport = port; 0267 } 0268 if (xvport == port) 0269 have_freq = freq_found; 0270 XvEncodingInfo * encodings = 0L; 0271 unsigned nr_encode; 0272 XvQueryEncodings (display, port, &nr_encode, &encodings); 0273 if (encodings) { 0274 QDomElement port_item = doc.createElement (QString("Port")); 0275 port_item.setAttribute (attvalue, QString::number (port)); 0276 if (freq_found) 0277 port_item.setAttribute (QString("FREQ"), QString("1")); 0278 for (unsigned i = 0; i < nr_encode; i++) { 0279 if (strcmp (encodings[i].name, "XV_IMAGE")) { 0280 if (xvport == port && xv_encoding < 0 && !xv_norm.isEmpty () && QString (encodings[i].name).lower ().startsWith(xv_norm.lower ())) 0281 xv_encoding = encodings[i].encoding_id; 0282 if (port == xvport && encodings[i].encoding_id == xv_encoding) { 0283 movie_width = encodings[i].width; 0284 movie_height = encodings[i].height; 0285 } 0286 QDomElement item = doc.createElement (QString ("Input")); 0287 item.setAttribute (attvalue, QString::number (encodings[i].encoding_id)); 0288 item.setAttribute (attname, QString (encodings[i].name)); 0289 port_item.appendChild (item); 0290 fprintf (stderr, " encoding: %d %s\n", ( int ) encodings[i].encoding_id, encodings[i].name); 0291 } 0292 } 0293 elm.appendChild (port_item); 0294 XvFreeEncodingInfo (encodings); 0295 } 0296 } 0297 } 0298 root.appendChild (elm); 0299 XvFreeAdaptorInfo(ai); 0300 } 0301 doc.appendChild (root); 0302 QCString exp = doc.toCString (); 0303 config_buf = exp; 0304 //fprintf (stderr, "%s\n", (const char *)exp); 0305 config_buf.resize (exp.length ()); // strip terminating \0 0306 0307 if (xvport <= 0) { 0308 fprintf (stderr, "no valid xvport found\n"); 0309 xv_success = false; 0310 return; 0311 } 0312 if (window_created) { 0313 fprintf (stderr, "map %lu\n", wid); 0314 if (movie_width > 0 && movie_height > 0) 0315 XResizeWindow (display, wid, movie_width, movie_height); 0316 XMapRaised(display, wid); 0317 XSync(display, False); 0318 } 0319 XUnlockDisplay(display); 0320 if (!xv_success) 0321 fprintf (stderr, "Failed to init %d port\n", xvport); 0322 } 0323 0324 KXVideoPlayer::~KXVideoPlayer () { 0325 if (window_created) { 0326 XLockDisplay (display); 0327 fprintf (stderr, "unmap %lu\n", wid); 0328 XUnmapWindow (display, wid); 0329 XDestroyWindow(display, wid); 0330 XSync (display, False); 0331 XUnlockDisplay (display); 0332 } 0333 xvapp = 0L; 0334 } 0335 0336 void getConfigEntries (QByteArray & buf) { 0337 QDomDocument doc; 0338 QDomElement root = doc.createElement (QString ("document")); 0339 doc.appendChild (root); 0340 QCString exp = doc.toCString (); 0341 buf = exp; 0342 buf.resize (exp.length ()); // strip terminating \0 0343 } 0344 0345 void KXVideoPlayer::play () { 0346 fprintf (stderr, "play xv://%d:%d/%d\n", xvport, xv_encoding, xv_frequency); 0347 if (!xv_success) 0348 return; 0349 if (callback && movie_width > 0 && movie_height > 0) 0350 callback->movieParams (0, 0, movie_width, movie_height, 1.0*movie_width/movie_height, QStringList (), QStringList ()); 0351 XLockDisplay (display); 0352 if (!running && XvGrabPort (display, xvport, CurrentTime) == Success) { 0353 gc = XCreateGC (display, wid, 0, NULL); 0354 XvSelectPortNotify (display, xvport, 1); 0355 XvSelectVideoNotify (display, wid, 1); 0356 int nr, cur_val; 0357 if (XvGetPortAttribute (display, xvport, xv_autopaint_colorkey_atom, &cur_val) == Success && cur_val == 0) { 0358 fprintf (stderr, "XV_AUTOPAINT_COLORKEY is 0\n"); 0359 XvSetPortAttribute (display, xvport, xv_autopaint_colorkey_atom, 1); 0360 reset_xv_autopaint_colorkey = true; 0361 } 0362 XvAttribute *attributes = XvQueryPortAttributes (display, xvport, &nr); 0363 if (attributes) { 0364 for (int i = 0; i < nr; i++) { 0365 Limit * limit = 0; 0366 Atom atom = XInternAtom (display, attributes[i].name, false); 0367 if (atom == xv_volume_atom) { 0368 limit = xv_limits + limit_volume; 0369 XvGetPortAttribute (display, xvport, 0370 xv_volume_atom, ¤t_volume); 0371 } else if (atom == xv_hue_atom) { 0372 limit = xv_limits + limit_hue; 0373 } else if (atom == xv_saturation_atom) { 0374 limit = xv_limits + limit_saturation; 0375 } else if (atom == xv_brightness_atom) { 0376 limit = xv_limits + limit_brightness; 0377 } else if (atom == xv_contrast_atom) { 0378 limit = xv_limits + limit_contrast; 0379 } else 0380 continue; 0381 limit->min = attributes[i].min_value; 0382 limit->max = attributes[i].max_value; 0383 } 0384 XFree (attributes); 0385 } 0386 if (xv_frequency > 0) 0387 XvSetPortAttribute (display, xvport, xv_freq_atom, int (1.0*xv_frequency/62.5)); 0388 if (xv_encoding >= 0) 0389 XvSetPortAttribute (display, xvport, xv_enc_atom, xv_encoding); 0390 if (XvGetPortAttribute (display, xvport, xv_mute_atom, &cur_val) == 0391 Success && cur_val == 1) { 0392 fprintf (stderr, "XV_MUTE is 1\n"); 0393 if (xv_limits[limit_volume].min != xv_limits[limit_volume].max) { 0394 tmp_volume = xv_limits[limit_volume].min; 0395 XvSetPortAttribute(display, xvport, xv_volume_atom, tmp_volume); 0396 mute_timer = startTimer (start_vol_timeout); 0397 } 0398 XvSetPortAttribute (display, xvport, xv_mute_atom, 0); 0399 reset_xv_mute = true; 0400 } 0401 //XvGetVideo (.. 0402 running = true; 0403 } 0404 if (running) { 0405 putVideo (); 0406 if (callback) { 0407 callback->playing (0); 0408 callback->statusMessage (0, (int) KMPlayer::Callback::stat_hasvideo, QString ()); 0409 } 0410 } 0411 XUnlockDisplay (display); 0412 } 0413 0414 void KXVideoPlayer::stop () { 0415 if (mute_timer) { 0416 killTimer (mute_timer); 0417 mute_timer = 0; 0418 } 0419 if (running) { 0420 running = false; 0421 XLockDisplay (display); 0422 XvStopVideo (display, xvport, wid); 0423 if (reset_xv_autopaint_colorkey) { 0424 XvSetPortAttribute (display, xvport, xv_autopaint_colorkey_atom, 0); 0425 reset_xv_autopaint_colorkey = false; 0426 } 0427 if (reset_xv_mute) { 0428 XvSetPortAttribute (display, xvport, xv_mute_atom, 1); 0429 reset_xv_mute = false; 0430 } 0431 XvUngrabPort (display, xvport, CurrentTime); 0432 XFreeGC (display, gc); 0433 XClearArea (display, wid, 0, 0, 0, 0, true); 0434 XUnlockDisplay (display); 0435 } 0436 if (callback) 0437 callback->finished (0); 0438 else 0439 QTimer::singleShot (0, qApp, SLOT (quit ())); 0440 } 0441 0442 void KXVideoPlayer::finished () { 0443 QTimer::singleShot (10, this, SLOT (stop ())); 0444 } 0445 0446 void KXVideoPlayer::saturation (int val) { 0447 XLockDisplay(display); 0448 XvSetPortAttribute (display, xvport, xv_saturation_atom, val); 0449 XFlush (display); 0450 XUnlockDisplay(display); 0451 } 0452 0453 void KXVideoPlayer::hue (int val) { 0454 XLockDisplay(display); 0455 XvSetPortAttribute (display, xvport, xv_hue_atom, val); 0456 XFlush (display); 0457 XUnlockDisplay(display); 0458 } 0459 0460 void KXVideoPlayer::contrast (int val) { 0461 XLockDisplay(display); 0462 XvSetPortAttribute (display, xvport, xv_contrast_atom, val); 0463 XFlush (display); 0464 XUnlockDisplay(display); 0465 } 0466 0467 void KXVideoPlayer::brightness (int val) { 0468 XLockDisplay(display); 0469 XvSetPortAttribute (display, xvport, xv_brightness_atom, val); 0470 XFlush (display); 0471 XUnlockDisplay(display); 0472 } 0473 0474 void KXVideoPlayer::volume (int val) { 0475 current_volume = val; 0476 if (mute_timer) 0477 return; 0478 XLockDisplay(display); 0479 XvSetPortAttribute (display, xvport, xv_volume_atom, val); 0480 XFlush (display); 0481 XUnlockDisplay(display); 0482 } 0483 0484 void KXVideoPlayer::frequency (int val) { 0485 // this doesn't work, changing frequency kills audio for me 0486 if (mute_timer) { 0487 killTimer (mute_timer); 0488 mute_timer = 0; 0489 } 0490 xv_frequency = val; 0491 if (running && have_freq) { 0492 XLockDisplay(display); 0493 if (xv_limits[limit_volume].min != xv_limits[limit_volume].max) { 0494 tmp_volume = xv_limits[limit_volume].min; 0495 XvSetPortAttribute (display, xvport, xv_volume_atom, tmp_volume); 0496 mute_timer = startTimer (start_vol_timeout); 0497 XFlush (display); 0498 XvSetPortAttribute (display, xvport, xv_mute_atom, 0); 0499 } 0500 XvSetPortAttribute (display, xvport, xv_freq_atom, int (1.0*val/6.25)); 0501 XFlush (display); 0502 XUnlockDisplay(display); 0503 } 0504 } 0505 0506 void KXVideoPlayer::saveState (QSessionManager & sm) { 0507 if (callback) 0508 sm.setRestartHint (QSessionManager::RestartNever); 0509 } 0510 0511 void KXVideoPlayer::timerEvent (QTimerEvent * e) { 0512 if (e->timerId () == mute_timer) { 0513 int step = (current_volume - xv_limits[limit_volume].min) / 20; 0514 if (step > 0 && tmp_volume == xv_limits[limit_volume].min) { 0515 killTimer (mute_timer); 0516 mute_timer = startTimer (inc_vol_timeout); 0517 } 0518 tmp_volume += step; 0519 if (tmp_volume >= current_volume || step <= 0) { 0520 tmp_volume = current_volume; 0521 killTimer (mute_timer); 0522 mute_timer = 0; 0523 } 0524 XLockDisplay(display); 0525 XvSetPortAttribute (display, xvport, xv_volume_atom, tmp_volume); 0526 XFlush (display); 0527 XUnlockDisplay(display); 0528 } else 0529 killTimer (e->timerId ()); 0530 } 0531 0532 class XEventThread : public QThread { 0533 protected: 0534 void run () { 0535 Time prev_click_time = 0; 0536 int prev_click_x = 0; 0537 int prev_click_y = 0; 0538 while (true) { 0539 XEvent xevent; 0540 XNextEvent(display, &xevent); 0541 switch(xevent.type) { 0542 case ClientMessage: 0543 if (xevent.xclient.format == 8 && 0544 !strncmp(xevent.xclient.data.b, "quit_now", 8)) { 0545 fprintf(stderr, "request quit\n"); 0546 return; 0547 } 0548 break; 0549 case KeyPress: { 0550 XKeyEvent kevent; 0551 KeySym ksym; 0552 char kbuf[256]; 0553 int len; 0554 kevent = xevent.xkey; 0555 XLockDisplay(display); 0556 len = XLookupString(&kevent, kbuf, sizeof(kbuf), &ksym, NULL); 0557 XUnlockDisplay(display); 0558 fprintf(stderr, "keypressed 0x%x 0x%x\n", ( int ) kevent.keycode, ( int ) ksym); 0559 switch (ksym) { 0560 case XK_q: 0561 case XK_Q: 0562 xvapp->lock (); 0563 xvapp->stop (); 0564 xvapp->unlock (); 0565 break; 0566 } 0567 break; 0568 } 0569 case Expose: 0570 if(xevent.xexpose.count != 0 || xevent.xexpose.window != wid) 0571 break; 0572 break; 0573 0574 case ConfigureNotify: 0575 if (::running) 0576 putVideo (); 0577 break; 0578 case XvVideoNotify: 0579 fprintf (stderr, "xvevent %lu\n", ((XvEvent*)&xevent)->xvvideo.reason); 0580 break; 0581 case ButtonPress: { 0582 XButtonEvent *bev = (XButtonEvent *) &xevent; 0583 int dx = prev_click_x - bev->x; 0584 int dy = prev_click_y - bev->y; 0585 if (bev->time - prev_click_time < 400 && 0586 (dx * dx + dy * dy) < 25) { 0587 xvapp->lock (); 0588 if (callback) 0589 callback->toggleFullScreen (0); 0590 xvapp->unlock (); 0591 } 0592 prev_click_time = bev->time; 0593 prev_click_x = bev->x; 0594 prev_click_y = bev->y; 0595 break; 0596 } 0597 default: 0598 if (xevent.type < LASTEvent) { 0599 //fprintf (stderr, "event %d\n", xevent.type); 0600 } 0601 } 0602 } 0603 } 0604 }; 0605 0606 int main(int argc, char **argv) { 0607 if (!XInitThreads ()) { 0608 fprintf (stderr, "XInitThreads () failed\n"); 0609 return 1; 0610 } 0611 display = XOpenDisplay(NULL); 0612 screen = XDefaultScreen(display); 0613 0614 unsigned int ver, rel, req, evb, err; 0615 if (XvQueryExtension (display, &ver, &rel, &req, &evb, &err) != Success) { 0616 fprintf (stderr, "XVideo not supported on display\n"); 0617 XCloseDisplay (display); 0618 return 1; 0619 } 0620 xv_enc_atom = XInternAtom (display, "XV_ENCODING", false); 0621 xv_hue_atom = XInternAtom (display, "XV_HUE", false); 0622 xv_saturation_atom = XInternAtom (display, "XV_SATURATION", false); 0623 xv_brightness_atom = XInternAtom (display, "XV_BRIGHTNESS", false); 0624 xv_contrast_atom = XInternAtom (display, "XV_CONTRAST", false); 0625 xv_freq_atom = XInternAtom (display, "XV_FREQ", false); 0626 xv_volume_atom = XInternAtom (display, "XV_VOLUME", false); 0627 xv_mute_atom = XInternAtom (display, "XV_MUTE", false); 0628 xv_autopaint_colorkey_atom = XInternAtom (display, "XV_AUTOPAINT_COLORKEY", false); 0629 0630 xvapp = new KXVideoPlayer (argc, argv); 0631 0632 for(int i = 1; i < argc; i++) { 0633 if (!strcmp (argv [i], "-port")) { 0634 xvport = strtol (argv [++i], 0L, 10); 0635 } else if (!strcmp (argv [i], "-wid") || !strcmp (argv [i], "-window-id")) { 0636 wid = atol (argv [++i]); 0637 window_created = false; 0638 } else if (!strcmp (argv [i], "-root")) { 0639 wid = XDefaultRootWindow (display); 0640 window_created = false; 0641 } else if (!strcmp (argv [i], "-window")) { 0642 ; 0643 } else if (!strcmp (argv [i], "-v")) { 0644 verbose = true; 0645 } else if (!strcmp (argv [i], "-c")) { 0646 wants_config = true; 0647 } else if (!strcmp (argv [i], "-f") && i < argc - 1) { 0648 strncpy (configfile, argv [++i], sizeof (configfile)); 0649 configfile[sizeof (configfile) - 1] = 0; 0650 } else if (!strcmp (argv [i], "-cb")) { 0651 QString str = argv [++i]; 0652 int pos = str.find ('/'); 0653 if (pos > -1) { 0654 fprintf (stderr, "callback is %s %s\n", str.left (pos).ascii (), str.mid (pos + 1).ascii ()); 0655 callback = new KMPlayer::Callback_stub 0656 (str.left (pos).ascii (), str.mid (pos + 1).ascii ()); 0657 } 0658 } else if (!strcmp (argv [i], "-enc")) { 0659 xv_encoding = strtol (argv [++i], 0L, 10); 0660 } else if (!strcmp (argv [i], "-norm")) { 0661 xv_norm = argv [++i]; 0662 } else if (!strcmp (argv [i], "-freq")) { 0663 xv_frequency = strtol (argv [++i], 0L, 10); 0664 } else { 0665 fprintf (stderr, "usage: %s [-port <xv port>] [-enc <encoding>] [-freq <frequency>] [-f <config file>] [-v] [(-wid|-window-id) <window>] [(-root|-window)] [-cb <DCOP callback name> [-c]]\n", argv[0]); 0666 delete xvapp; 0667 return 1; 0668 } 0669 } 0670 0671 DCOPClient dcopclient; 0672 dcopclient.registerAs ("kxvideoplayer"); 0673 Backend player; 0674 0675 XEventThread * eventThread = new XEventThread; 0676 eventThread->start (); 0677 0678 xvapp->init (); 0679 0680 if (callback) 0681 callback->started (dcopclient.appId (), config_buf); 0682 0683 xvapp->exec (); 0684 0685 XLockDisplay(display); 0686 XClientMessageEvent ev = { 0687 ClientMessage, 0, true, display, wid, 0688 XInternAtom (display, "XVIDEO", false), 8, {"quit_now"} 0689 }; 0690 XSendEvent (display, wid, false, StructureNotifyMask, (XEvent *) & ev); 0691 XFlush (display); 0692 XUnlockDisplay(display); 0693 eventThread->wait (500); 0694 delete eventThread; 0695 0696 xvapp->stop (); 0697 delete xvapp; 0698 0699 fprintf (stderr, "closing display\n"); 0700 XCloseDisplay (display); 0701 fprintf (stderr, "done\n"); 0702 return 0; 0703 } 0704 0705 #include "xvplayer.moc"