00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <fstream>
00034 #include <cstdlib>
00035 #include <cerrno>
00036 #include "mmsmedia/mmsdvd.h"
00037 extern "C" {
00038 #include <linux/cdrom.h>
00039 #include <sys/ioctl.h>
00040 #include <sys/types.h>
00041 #include <sys/stat.h>
00042 #include <fcntl.h>
00043 }
00044
00045 MMS_CREATEERROR(MMSDVDError);
00046
00047 #ifdef __HAVE_GSTREAMER__
00048 #endif
00049 #ifdef __HAVE_XINE__
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 static void queue_cb(void *userData, const xine_event_t *event) {
00062 MMSDVD *mmsdvd = (MMSDVD*)userData;
00063 xine_ui_message_data_t *msg = (xine_ui_message_data_t*)event->data;
00064
00065 switch(event->type) {
00066 case XINE_EVENT_UI_MESSAGE:
00067 if(msg->type == XINE_MSG_ENCRYPTED_SOURCE)
00068 mmsdvd->onError->emit(string("We don't support encrypted DVDs!"));
00069 else if(msg->explanation)
00070 mmsdvd->onError->emit(string((char*)msg + msg->parameters));
00071 break;
00072 case XINE_EVENT_UI_CHANNELS_CHANGED:
00073 mmsdvd->updateChannelInfo();
00074 break;
00075 }
00076 }
00077 #endif
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 void MMSDVD::checkDevice(const string device) {
00091 if (this->backend == MMSMEDIA_BE_GST) {
00092 #ifdef __HAVE_GSTREAMER__
00093 #endif
00094 }
00095 else {
00096 #ifdef __HAVE_XINE__
00097 string d = device;
00098 xine_health_check_t hc, *result;
00099
00100 if(d.length() == 0)
00101 d = "/dev/dvd";
00102
00103 hc.dvd_dev = xine_config_register_string(xine, "input.dvd_device", d.c_str(), "device used as dvd drive", NULL, 0, NULL, NULL);
00104 result = xine_health_check(&hc, CHECK_DVDROM);
00105 if(result->status != XINE_HEALTH_CHECK_OK) {
00106 if(d != "dev/dvd") {
00107 hc.dvd_dev = xine_config_register_string(xine, "input.dvd_device", "/dev/dvd", "device used as dvd drive", NULL, 0, NULL, NULL);
00108 result = xine_health_check(&hc, CHECK_DVDROM);
00109 if(result->status != XINE_HEALTH_CHECK_OK)
00110 throw MMSDVDError(0, "No DVD Device found at " + device + " and /dev/dvd");
00111 }
00112 else
00113 throw MMSDVDError(0, "No DVD Device found at /dev/dvd");
00114 }
00115
00116 this->device = d;
00117 DEBUGMSG("MMSMedia", "Using " + this->device + " as DVD device");
00118 #endif
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 MMSDVD::MMSDVD(MMSWindow *window, const string device, const bool verbose) :
00134 audioChannel(0),
00135 spuChannel(0),
00136 maxAudioChannels(0),
00137 maxSpuChannels(0) {
00138 MMSAV::initialize(verbose, window);
00139
00140
00141 checkDevice(device);
00142
00143
00144 MMSFBRectangle rect = window->getGeometry();
00145 this->windowWidth = rect.w;
00146 this->windowHeight = rect.h;
00147 }
00148
00149
00150
00151
00152 MMSDVD::~MMSDVD() {
00153 }
00154
00155 #if defined __HAVE_GSTREAMER__
00156 #elif defined __HAVE_XINE__
00157
00158
00159
00160 void MMSDVD::xineOpen() {
00161 MMSAV::xineOpen(queue_cb, (void*)this);
00162 }
00163 #endif
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 void MMSDVD::startPlaying(const bool cont) {
00174 string mrl = "dvd://" + this->device;
00175
00176
00177
00178 if(!cont) mrl += "/0";
00179 MMSAV::startPlaying(mrl, cont);
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 void MMSDVD::rewind() {
00189 DEBUGMSG("MMSMedia", "MMSDVD::rewind() not yet implemented");
00190 #if 0
00191 if(this->status != this->STATUS_NONE) {
00192 this->setStatus(this->STATUS_REWIND);
00193 xine_trick_mode (this->stream, XINE_TRICK_MODE_FAST_REWIND, 1);
00194 }
00195 #endif
00196 }
00197
00198
00199
00200
00201
00202
00203 void MMSDVD::previous() {
00204 if (this->backend == MMSMEDIA_BE_GST) {
00205 #ifdef __HAVE_GSTREAMER__
00206 #endif
00207 }
00208 else {
00209 #ifdef __HAVE_XINE__
00210 this->sendEvent(XINE_EVENT_INPUT_PREVIOUS);
00211 #endif
00212 }
00213 this->setStatus(this->STATUS_PREVIOUS);
00214 }
00215
00216
00217
00218
00219
00220
00221 void MMSDVD::next() {
00222 if (this->backend == MMSMEDIA_BE_GST) {
00223 #ifdef __HAVE_GSTREAMER__
00224 #endif
00225 }
00226 else {
00227 #ifdef __HAVE_XINE__
00228 this->sendEvent(XINE_EVENT_INPUT_NEXT);
00229 #endif
00230 }
00231 this->setStatus(this->STATUS_NEXT);
00232 }
00233
00234
00235
00236
00237
00238
00239 void MMSDVD::anglePrevious() {
00240 if (this->backend == MMSMEDIA_BE_GST) {
00241 #ifdef __HAVE_GSTREAMER__
00242 #endif
00243 }
00244 else {
00245 #ifdef __HAVE_XINE__
00246 this->sendEvent(XINE_EVENT_INPUT_ANGLE_PREVIOUS);
00247 #endif
00248 }
00249 this->setStatus(this->STATUS_ANGLE_PREVIOUS);
00250 }
00251
00252
00253
00254
00255
00256
00257 void MMSDVD::angleNext() {
00258 if (this->backend == MMSMEDIA_BE_GST) {
00259 #ifdef __HAVE_GSTREAMER__
00260 #endif
00261 }
00262 else {
00263 #ifdef __HAVE_XINE__
00264 this->sendEvent(XINE_EVENT_INPUT_ANGLE_NEXT);
00265 #endif
00266 }
00267 this->setStatus(this->STATUS_ANGLE_NEXT);
00268 }
00269
00270
00271
00272
00273
00274
00275 void MMSDVD::audioChannelPrevious() {
00276 if (this->backend == MMSMEDIA_BE_GST) {
00277 #ifdef __HAVE_GSTREAMER__
00278 #endif
00279 }
00280 else {
00281 #ifdef __HAVE_XINE__
00282 if(--audioChannel < 0)
00283 audioChannel = maxAudioChannels;
00284 xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, audioChannel);
00285 #endif
00286 }
00287 this->setStatus(this->STATUS_AUDIO_PREVIOUS);
00288 }
00289
00290
00291
00292
00293
00294
00295 void MMSDVD::audioChannelNext() {
00296 if (this->backend == MMSMEDIA_BE_GST) {
00297 #ifdef __HAVE_GSTREAMER__
00298 #endif
00299 }
00300 else {
00301 #ifdef __HAVE_XINE__
00302 if(++audioChannel >= maxAudioChannels)
00303 audioChannel = 0;
00304 xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, audioChannel);
00305 #endif
00306 }
00307 this->setStatus(this->STATUS_AUDIO_NEXT);
00308 }
00309
00310
00311
00312
00313
00314
00315 void MMSDVD::spuChannelPrevious() {
00316 if (this->backend == MMSMEDIA_BE_GST) {
00317 #ifdef __HAVE_GSTREAMER__
00318 #endif
00319 }
00320 else {
00321 #ifdef __HAVE_XINE__
00322 if(--spuChannel < -1)
00323 spuChannel = maxSpuChannels;
00324 xine_set_param(this->stream, XINE_PARAM_SPU_CHANNEL, spuChannel);
00325 #endif
00326 }
00327 this->setStatus(this->STATUS_SPU_PREVIOUS);
00328 }
00329
00330
00331
00332
00333
00334
00335 void MMSDVD::spuChannelNext() {
00336 if (this->backend == MMSMEDIA_BE_GST) {
00337 #ifdef __HAVE_GSTREAMER__
00338 #endif
00339 }
00340 else {
00341 #ifdef __HAVE_XINE__
00342 if(++spuChannel >= maxSpuChannels)
00343 spuChannel = -1;
00344 xine_set_param(this->stream, XINE_PARAM_SPU_CHANNEL, spuChannel);
00345 #endif
00346 }
00347 this->setStatus(this->STATUS_SPU_NEXT);
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 void MMSDVD::eject() {
00357
00358 this->setStatus(this->STATUS_NONE);
00359
00360 if (this->backend == MMSMEDIA_BE_GST) {
00361 #ifdef __HAVE_GSTREAMER__
00362 #endif
00363 }
00364 else {
00365 #ifdef __HAVE_XINE__
00366 if(this->stream)
00367 xine_dispose(this->stream);
00368 this->stream = 0;
00369
00370 #endif
00371 }
00372
00373 int status = -1;
00374 int fd = open(device.c_str(), O_RDONLY|O_NONBLOCK);
00375
00376 if(fd < 0) {
00377 DEBUGMSG("MMSDVD", "Eject failed (can't open device: %s.)", strerror(errno));
00378 return;
00379 }
00380
00381 #if defined(CDROMEJECT)
00382 status = ioctl(fd, CDROMEJECT);
00383 #elif defined(CDIOCEJECT)
00384 status = ioctl(fd, CDIOCEJECT);
00385 #endif
00386
00387 close(fd);
00388 if(status != 0) {
00389 DEBUGMSG("MMSDVD", "Eject failed: %s.", strerror(errno));
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 void MMSDVD::menuUp() {
00402 if (this->backend == MMSMEDIA_BE_GST) {
00403 #ifdef __HAVE_GSTREAMER__
00404 #endif
00405 }
00406 else {
00407 #ifdef __HAVE_XINE__
00408 this->sendEvent(XINE_EVENT_INPUT_UP);
00409 #endif
00410 }
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 void MMSDVD::menuDown() {
00422 if (this->backend == MMSMEDIA_BE_GST) {
00423 #ifdef __HAVE_GSTREAMER__
00424 #endif
00425 }
00426 else {
00427 #ifdef __HAVE_XINE__
00428 this->sendEvent(XINE_EVENT_INPUT_DOWN);
00429 #endif
00430 }
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 void MMSDVD::menuLeft() {
00442 if (this->backend == MMSMEDIA_BE_GST) {
00443 #ifdef __HAVE_GSTREAMER__
00444 #endif
00445 }
00446 else {
00447 #ifdef __HAVE_XINE__
00448 this->sendEvent(XINE_EVENT_INPUT_LEFT);
00449 #endif
00450 }
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 void MMSDVD::menuRight() {
00462 if (this->backend == MMSMEDIA_BE_GST) {
00463 #ifdef __HAVE_GSTREAMER__
00464 #endif
00465 }
00466 else {
00467 #ifdef __HAVE_XINE__
00468 this->sendEvent(XINE_EVENT_INPUT_RIGHT);
00469 #endif
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 void MMSDVD::menuSelect() {
00482 if (this->backend == MMSMEDIA_BE_GST) {
00483 #ifdef __HAVE_GSTREAMER__
00484 #endif
00485 }
00486 else {
00487 #ifdef __HAVE_XINE__
00488 this->sendEvent(XINE_EVENT_INPUT_SELECT);
00489 #endif
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 void MMSDVD::showMainMenu() {
00500 if (this->backend == MMSMEDIA_BE_GST) {
00501 #ifdef __HAVE_GSTREAMER__
00502 #endif
00503 }
00504 else {
00505 #ifdef __HAVE_XINE__
00506 this->sendEvent(XINE_EVENT_INPUT_MENU1);
00507 #endif
00508 }
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 void MMSDVD::mouseEvent(const unsigned int event, const unsigned int x, const unsigned int y) const {
00524 if (this->backend == MMSMEDIA_BE_GST) {
00525 #ifdef __HAVE_GSTREAMER__
00526 #endif
00527 }
00528 else {
00529 #ifdef __HAVE_XINE__
00530 xine_event_t e;
00531 xine_input_data_t eData;
00532
00533 int streamW = xine_get_stream_info(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH);
00534 int streamH = xine_get_stream_info(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
00535
00536 e.type = event;
00537 e.data = &eData;
00538 e.data_length = sizeof(xine_input_data_t);
00539 eData.button = 1;
00540 eData.x = (int)((float)x / this->windowWidth * streamW);
00541 eData.y = (int)((float)y / this->windowHeight * streamH);
00542 xine_event_send(this->stream, &e);
00543 #endif
00544 }
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 void MMSDVD::mouseButton(const unsigned int x, const unsigned int y) const {
00556 if (this->backend == MMSMEDIA_BE_GST) {
00557 #ifdef __HAVE_GSTREAMER__
00558 printf("button pressed\n");
00559
00560
00561
00562
00563
00564 #endif
00565 }
00566 else {
00567 #ifdef __HAVE_XINE__
00568 this->mouseEvent(XINE_EVENT_INPUT_MOUSE_BUTTON, x, y);
00569 #endif
00570 }
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 void MMSDVD::mouseMove(const unsigned int x, const unsigned int y) const {
00582 if (this->backend == MMSMEDIA_BE_GST) {
00583 #ifdef __HAVE_GSTREAMER__
00584 #endif
00585 }
00586 else {
00587 #ifdef __HAVE_XINE__
00588 this->mouseEvent(XINE_EVENT_INPUT_MOUSE_MOVE, x, y);
00589 #endif
00590 }
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 bool MMSDVD::inMenu() {
00603 return (this->getChapterNumber() == 0);
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 string MMSDVD::getTitle() {
00613 if (this->backend == MMSMEDIA_BE_GST) {
00614 #ifdef __HAVE_GSTREAMER__
00615
00616 return "";
00617 #endif
00618 }
00619 else {
00620 #ifdef __HAVE_XINE__
00621 if(this->status > STATUS_NONE) {
00622 char *title;
00623 title = (char*)xine_get_meta_info(this->stream, XINE_META_INFO_TITLE);
00624 if(title)
00625 return string(title);
00626 }
00627 else {
00628 char buf[32841];
00629 ifstream fstr(this->device.c_str(), ios::in | ios::binary);
00630 if(fstr) {
00631 if(fstr.read(buf, sizeof(buf) - 1)) {
00632 buf[sizeof(buf) - 1] = 0;
00633 return string(buf + 32808);
00634 }
00635 }
00636 }
00637
00638 return "";
00639 #endif
00640 }
00641
00642 throw MMSDVDError(0, "MMSDVD::getTitle() called but media backend does not match supported backends");
00643 }
00644
00645
00646
00647
00648
00649
00650 int MMSDVD::getChapterNumber() {
00651 if (this->backend == MMSMEDIA_BE_GST) {
00652 #ifdef __HAVE_GSTREAMER__
00653
00654 return 0;
00655 #endif
00656 }
00657 else {
00658 #ifdef __HAVE_XINE__
00659 return xine_get_stream_info(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER);
00660 #endif
00661 }
00662
00663 throw MMSDVDError(0, "MMSDVD::getChapterNumber() called but media backend does not match supported backends");
00664 }
00665
00666
00667
00668
00669
00670
00671 int MMSDVD::getChapterCount() {
00672 if (this->backend == MMSMEDIA_BE_GST) {
00673 #ifdef __HAVE_GSTREAMER__
00674
00675 return 0;
00676 #endif
00677 }
00678 else {
00679 #ifdef __HAVE_XINE__
00680 return xine_get_stream_info(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_COUNT);
00681 #endif
00682 }
00683
00684 throw MMSDVDError(0, "MMSDVD::getChapterCount() called but media backend does not match supported backends");
00685 }
00686
00687
00688
00689
00690
00691
00692 int MMSDVD::getTitleNumber() {
00693 if (this->backend == MMSMEDIA_BE_GST) {
00694 #ifdef __HAVE_GSTREAMER__
00695
00696 return 0;
00697 #endif
00698 }
00699 else {
00700 #ifdef __HAVE_XINE__
00701 return xine_get_stream_info(this->stream, XINE_STREAM_INFO_DVD_TITLE_NUMBER);
00702 #endif
00703 }
00704
00705 throw MMSDVDError(0, "MMSDVD::getTitleNumber() called but media backend does not match supported backends");
00706 }
00707
00708
00709
00710
00711
00712
00713 int MMSDVD::getTitleCount() {
00714 if (this->backend == MMSMEDIA_BE_GST) {
00715 #ifdef __HAVE_GSTREAMER__
00716
00717 return 0;
00718 #endif
00719 }
00720 else {
00721 #ifdef __HAVE_XINE__
00722 return xine_get_stream_info(this->stream, XINE_STREAM_INFO_DVD_TITLE_COUNT);
00723 #endif
00724 }
00725
00726 throw MMSDVDError(0, "MMSDVD::getTitleCount() called but media backend does not match supported backends");
00727 }
00728
00729
00730
00731
00732
00733 void MMSDVD::updateChannelInfo() {
00734 if (this->backend == MMSMEDIA_BE_GST) {
00735 #ifdef __HAVE_GSTREAMER__
00736 #endif
00737 }
00738 else {
00739 #ifdef __HAVE_XINE__
00740 this->maxAudioChannels = xine_get_stream_info(this->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
00741 this->maxSpuChannels = xine_get_stream_info(this->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
00742 #endif
00743 }
00744 }