summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2002-09-20 12:53:53 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2002-09-20 12:53:53 +0000
commit0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb (patch)
tree534a685276a6f33fe77692a721530a927b95185c /src
parent44a2823e79fcf9b1002f7bf537fc9c7a9b7913b3 (diff)
downloadxine-lib-0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb.tar.gz
xine-lib-0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb.tar.bz2
sync to latest libdvdnav cvs version
CVS patchset: 2718 CVS date: 2002/09/20 12:53:53
Diffstat (limited to 'src')
-rw-r--r--src/input/libdvdnav/Makefile.am2
-rw-r--r--src/input/libdvdnav/diff_against_cvs.patch20
-rw-r--r--src/input/libdvdnav/dvd_types.h3
-rw-r--r--src/input/libdvdnav/dvdnav.c27
-rw-r--r--src/input/libdvdnav/dvdnav.h34
-rw-r--r--src/input/libdvdnav/highlight.c103
-rw-r--r--src/input/libdvdnav/navigation.c25
-rw-r--r--src/input/libdvdnav/remap.c225
-rw-r--r--src/input/libdvdnav/remap.h13
-rw-r--r--src/input/libdvdnav/settings.c27
-rw-r--r--src/input/libdvdnav/vm.c67
-rw-r--r--src/input/libdvdnav/vm.h6
12 files changed, 467 insertions, 85 deletions
diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am
index e15771a77..559563aa6 100644
--- a/src/input/libdvdnav/Makefile.am
+++ b/src/input/libdvdnav/Makefile.am
@@ -11,6 +11,7 @@ libdvdnav_la_SOURCES = \
highlight.c \
navigation.c \
read_cache.c \
+ remap.c \
searching.c \
settings.c \
vm.c \
@@ -23,6 +24,7 @@ noinst_HEADERS = \
dvdnav.h \
dvdnav_events.h \
dvdnav_internal.h \
+ remap.h \
vm.h \
vmcmd.h \
read_cache.h \
diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch
index 331435d00..df4658ee3 100644
--- a/src/input/libdvdnav/diff_against_cvs.patch
+++ b/src/input/libdvdnav/diff_against_cvs.patch
@@ -36,23 +36,25 @@
#include <stdlib.h>
#include <stdio.h>
-@@ -179,7 +179,7 @@
+@@ -181,7 +181,7 @@
struct timeval time;
/* Create a new structure */
-- fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://dvd.sf.net\n");
-+ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://xine.sf.net\n");
+- fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://dvd.sf.net\n", VERSION);
++ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION);
- /* FIXME: We malloc() here, but if an error occurs inside dvdnav_open(),
- * we return but never free() it.
+ (*dest) = NULL;
+ this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
--- src/input/libdvdnav/dvdnav.h Thu Jul 25 17:26:00 2002
+++ src/input/libdvdnav/dvdnav.h Fri Aug 9 22:01:19 2002
-@@ -40,7 +40,7 @@
+@@ -40,8 +40,8 @@
/* Various useful types */
#include "dvd_types.h"
-#include <dvdread/dvd_reader.h>
+-#include <dvdread/ifo_types.h> /* For vm_cmd_t */
+#include "dvd_reader.h"
++#include "ifo_types.h" /* For vm_cmd_t */
/**
* Opaque data-type can be viewed as a 'DVD handle'. You should get
@@ -124,9 +126,9 @@
--- src/input/libdvdnav/vm.c Sat Jul 6 18:12:09 2002
+++ src/input/libdvdnav/vm.c Fri Aug 9 22:03:48 2002
-@@ -34,8 +34,8 @@
- #include <inttypes.h>
- #include <assert.h>
+@@ -37,8 +37,8 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
diff --git a/src/input/libdvdnav/dvd_types.h b/src/input/libdvdnav/dvd_types.h
index d19bce84a..2c6967b8e 100644
--- a/src/input/libdvdnav/dvd_types.h
+++ b/src/input/libdvdnav/dvd_types.h
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dvd_types.h,v 1.1 2002/08/08 17:49:21 richwareham Exp $
+ * $Id: dvd_types.h,v 1.2 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -296,5 +296,4 @@ typedef struct {
uint32_t buttonN; /*!< Button number for the SPU decoder. */
} dvdnav_highlight_area_t;
-
#endif /* DVD_H_INCLUDED */
diff --git a/src/input/libdvdnav/dvdnav.c b/src/input/libdvdnav/dvdnav.c
index d1a4e7318..7e209d3a8 100644
--- a/src/input/libdvdnav/dvdnav.c
+++ b/src/input/libdvdnav/dvdnav.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dvdnav.c,v 1.7 2002/09/04 11:07:47 mroi Exp $
+ * $Id: dvdnav.c,v 1.8 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -40,6 +40,8 @@
#include <stdio.h>
#include <sys/time.h>
+#include "remap.h"
+
/*
* NOTE:
* All NLCK_*() function are not mutex locked, this made them reusable in
@@ -179,11 +181,8 @@ dvdnav_status_t dvdnav_open(dvdnav_t** dest, char *path) {
struct timeval time;
/* Create a new structure */
- fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://xine.sf.net\n");
+ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION);
- /* FIXME: We malloc() here, but if an error occurs inside dvdnav_open(),
- * we return but never free() it.
- */
(*dest) = NULL;
this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
if(!this)
@@ -199,10 +198,15 @@ dvdnav_status_t dvdnav_open(dvdnav_t** dest, char *path) {
this->vm = vm_new_vm();
if(!this->vm) {
printerr("Error initialising the DVD VM");
+ pthread_mutex_destroy(&this->vm_lock);
+ free(this);
return S_ERR;
}
if(vm_reset(this->vm, path) == -1) {
printerr("Error starting the VM / opening the DVD device");
+ pthread_mutex_destroy(&this->vm_lock);
+ vm_free_vm(this->vm);
+ free(this);
return S_ERR;
}
@@ -593,13 +597,13 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf,
fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_letterbox=%d\n",stream_change.physical_letterbox);
fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_pan_scan=%d\n",stream_change.physical_pan_scan);
#endif
- pthread_mutex_unlock(&this->vm_lock);
if (stream_change.physical_wide != -1 &&
stream_change.physical_letterbox != -1 &&
stream_change.physical_pan_scan != -1) {
#ifdef LOG_DEBUG
fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE returning S_OK\n");
#endif
+ pthread_mutex_unlock(&this->vm_lock);
return S_OK;
}
}
@@ -782,6 +786,14 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf,
/* Perform the jump if necessary (this is always a
* VOBU boundary). */
+ if (this->vm->map) {
+ this->vobu.vobu_next = remap_block( this->vm->map,
+ this->vm->state.domain, this->vm->state.TTN_REG,
+ this->vm->state.pgN,
+ this->vobu.vobu_start, this->vobu.vobu_next);
+ }
+
+
//result = DVDReadBlocks(this->file, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf);
result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf);
@@ -998,6 +1010,9 @@ uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) {
/*
* $Log: dvdnav.c,v $
+ * Revision 1.8 2002/09/20 12:53:53 mroi
+ * sync to latest libdvdnav cvs version
+ *
* Revision 1.7 2002/09/04 11:07:47 mroi
* sync to libdvdnav cvs
*
diff --git a/src/input/libdvdnav/dvdnav.h b/src/input/libdvdnav/dvdnav.h
index 0160cc05e..2af610b26 100644
--- a/src/input/libdvdnav/dvdnav.h
+++ b/src/input/libdvdnav/dvdnav.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dvdnav.h,v 1.3 2002/08/09 22:52:14 mroi Exp $
+ * $Id: dvdnav.h,v 1.4 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -41,6 +41,7 @@ extern "C" {
#include "dvd_types.h"
#include "dvd_reader.h"
+#include "ifo_types.h" /* For vm_cmd_t */
/**
* Opaque data-type can be viewed as a 'DVD handle'. You should get
@@ -274,9 +275,10 @@ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int *titles);
* Returns the number of programs within the current title.
*
* \param self Pointer to dvdnav_t associated with this operation.
- * \param programs Pointer to int to receive number of programs.
+ * \param titles int to select title.
+ * \param parts Pointer to int to receive number of parts.
*/
-dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *self, int *programs);
+dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int title, int *parts);
/**
* If we are currently in a still-frame this function skips it (or attempts to).
@@ -532,31 +534,31 @@ dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32
*
* \param self Pointer to dvdnav_t associated with this operation.
*/
-dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self);
+dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci);
/**
* Move button highlight around as suggested by function name (e.g. with arrow keys).
*
* \param self Pointer to dvdnav_t associated with this operation.
*/
-dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self);
+dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci);
/**
* Move button highlight around as suggested by function name (e.g. with arrow keys).
*
* \param self Pointer to dvdnav_t associated with this operation.
*/
-dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self);
+dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci);
/**
* Move button highlight around as suggested by function name (e.g. with arrow keys).
*
* \param self Pointer to dvdnav_t associated with this operation.
*/
-dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self);
+dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci);
/**
* Activate (press) the currently highlighted button.
* \param self Pointer to dvdnav_t associated with this operation.
*/
-dvdnav_status_t dvdnav_button_activate(dvdnav_t *self);
+dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci);
/**
* Highlight a specific button.
@@ -564,7 +566,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *self);
* \param self Pointer to dvdnav_t associated with this operation.
* \param button 1..39 -- Button number to activate.
*/
-dvdnav_status_t dvdnav_button_select(dvdnav_t *self, int button);
+dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int button);
/**
* Activate (press) specified button.
@@ -572,7 +574,15 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *self, int button);
* \param self Pointer to dvdnav_t associated with this operation.
* \param button 1..39 -- Button number to activate.
*/
-dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, int button);
+dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int button);
+
+/**
+ * Activate (press) a button and execute specified command.
+ *
+ * \param self Pointer to dvdnav_t associated with this operation.
+ * \param cmd DVD Command to execute.
+ */
+dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd);
/**
* Select button at specified (image) co-ordinates.
@@ -581,7 +591,7 @@ dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, int button);
* \param x X co-ordinate in image.
* \param y Y xo-ordinate in image.
*/
-dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, int x, int y);
+dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int x, int y);
/**
* Activate (press) button at specified co-ordinates.
@@ -590,7 +600,7 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, int x, int y);
* \param x X co-ordinate in image.
* \param y Y xo-ordinate in image.
*/
-dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, int x, int y);
+dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int x, int y);
/**
* @}
diff --git a/src/input/libdvdnav/highlight.c b/src/input/libdvdnav/highlight.c
index 8beacd2ca..d0cfac713 100644
--- a/src/input/libdvdnav/highlight.c
+++ b/src/input/libdvdnav/highlight.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: highlight.c,v 1.5 2002/09/04 11:07:47 mroi Exp $
+ * $Id: highlight.c,v 1.6 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -217,7 +217,7 @@ dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int* button) {
return S_OK;
}
-btni_t *__get_current_button(dvdnav_t *this) {
+btni_t *__get_current_button(dvdnav_t *this, pci_t *pci) {
int button = 0;
if(dvdnav_get_current_highlight(this, &button) != S_OK) {
@@ -228,16 +228,16 @@ btni_t *__get_current_button(dvdnav_t *this) {
nav_print_PCI(&(this->pci));
#endif
- return &(this->pci.hli.btnit[button-1]);
+ return &(pci->hli.btnit[button-1]);
}
-dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this) {
+dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!this)
return S_ERR;
- if((button_ptr = __get_current_button(this)) == NULL) {
+ if((button_ptr = __get_current_button(this, pci)) == NULL) {
return S_ERR;
}
if (button_ptr->auto_action_mode == 1) {
@@ -247,74 +247,74 @@ dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this) {
}
-dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this) {
+dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!this)
return S_ERR;
- if((button_ptr = __get_current_button(this)) == NULL) {
+ if((button_ptr = __get_current_button(this, pci)) == NULL) {
return S_ERR;
}
- dvdnav_button_select(this, button_ptr->up);
- if (dvdnav_button_auto_action(this) ) {
- dvdnav_button_activate(this);
+ dvdnav_button_select(this, pci, button_ptr->up);
+ if (dvdnav_button_auto_action(this, pci) ) {
+ dvdnav_button_activate(this, pci);
}
return S_OK;
}
-dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this) {
+dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!this)
return S_ERR;
- if((button_ptr = __get_current_button(this)) == NULL) {
+ if((button_ptr = __get_current_button(this, pci)) == NULL) {
return S_ERR;
}
- dvdnav_button_select(this, button_ptr->down);
- if (dvdnav_button_auto_action(this) ) {
- dvdnav_button_activate(this);
+ dvdnav_button_select(this, pci, button_ptr->down);
+ if (dvdnav_button_auto_action(this, pci) ) {
+ dvdnav_button_activate(this, pci);
}
return S_OK;
}
-dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this) {
+dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!this)
return S_ERR;
- if((button_ptr = __get_current_button(this)) == NULL) {
+ if((button_ptr = __get_current_button(this, pci)) == NULL) {
printerr("Error fetching information on current button.");
return S_ERR;
}
- dvdnav_button_select(this, button_ptr->right);
- if (dvdnav_button_auto_action(this) ) {
- dvdnav_button_activate(this);
+ dvdnav_button_select(this, pci, button_ptr->right);
+ if (dvdnav_button_auto_action(this, pci) ) {
+ dvdnav_button_activate(this, pci);
}
return S_OK;
}
-dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this) {
+dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!this)
return S_ERR;
- if((button_ptr = __get_current_button(this)) == NULL) {
+ if((button_ptr = __get_current_button(this, pci)) == NULL) {
return S_ERR;
}
- dvdnav_button_select(this, button_ptr->left);
- if (dvdnav_button_auto_action(this) ) {
- dvdnav_button_activate(this);
+ dvdnav_button_select(this, pci, button_ptr->left);
+ if (dvdnav_button_auto_action(this, pci) ) {
+ dvdnav_button_activate(this, pci);
}
return S_OK;
@@ -357,7 +357,7 @@ dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32
return S_OK;
}
-dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) {
+dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
int button;
btni_t *button_ptr = NULL;
@@ -374,7 +374,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) {
/* FIXME: dvdnav_button_select should really return a
* special case for explicit NO-BUTTONS.
*/
- if(dvdnav_button_select(this, button) != S_OK) {
+ if(dvdnav_button_select(this, pci, button) != S_OK) {
/* Special code to handle still menus with no buttons.
* the navigation is expected to report to the appicatino that a STILL is
* underway. In turn, the application is supposed to report to the user
@@ -395,7 +395,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) {
return S_ERR;
}
/* FIXME: The button command should really be passed in the API instead. */
- button_ptr = __get_current_button(this);
+ button_ptr = __get_current_button(this, pci);
/* Finally, make the VM execute the appropriate code and
* scedule a jump */
#ifdef BUTTON_TESTING
@@ -410,7 +410,32 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) {
return S_OK;
}
-dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) {
+dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd)
+{
+ if(!this || !this->vm)
+ return S_ERR;
+ pthread_mutex_lock(&this->vm_lock);
+ /* make the VM execute the appropriate code and
+ * schedule a jump */
+#ifdef BUTTON_TESTING
+ fprintf(MSG_OUT, "libdvdnav:dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n");
+#endif
+ if(button > 0) {
+ printerrf("Select button number %i\n ",
+ button);
+ this->vm->state.HL_BTNN_REG = (button << 10);
+ if( (vm_eval_cmd(this->vm, cmd)) == 1) {
+ /* Command caused a jump */
+ this->vm->hop_channel++;
+ }
+ }
+ /* Always remove still, because some still menus have no buttons. */
+ this->position_current.still = 0;
+ pthread_mutex_unlock(&this->vm_lock);
+ return S_OK;
+}
+
+dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int button) {
if(!this) {
printerrf("Unable to select button number %i as this state bad",
@@ -424,7 +449,7 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) {
/* Set the highlight SPRM if the passed button was valid*/
/* FIXME: this->pci should be provided by the application. */
- if((button <= 0) || (button > this->pci.hli.hl_gi.btn_ns)) {
+ if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
printerrf("Unable to select button number %i as it doesn't exist",
button);
return S_ERR;
@@ -438,18 +463,18 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) {
return S_OK;
}
-dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this,
+dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci,
int button) {
/* A trivial function */
- if(dvdnav_button_select(this, button) != S_ERR) {
- return dvdnav_button_activate(this);
+ if(dvdnav_button_select(this, pci, button) != S_ERR) {
+ return dvdnav_button_activate(this, pci);
}
/* Should never get here without an error */
return S_ERR;
}
-dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) {
+dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int x, int y) {
int button, cur_button;
uint32_t best,dist;
int mx,my,dx,dy,d;
@@ -467,7 +492,7 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) {
dist = 0x08000000; /* >> than (720*720)+(567*567); */
/* Loop through each button */
- for(button=1; button <= this->pci.hli.hl_gi.btn_ns; button++) {
+ for(button=1; button <= pci->hli.hl_gi.btn_ns; button++) {
btni_t *button_ptr = NULL;
button_ptr = &(this->pci.hli.btnit[button-1]);
if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) &&
@@ -489,17 +514,17 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) {
/* As an efficiency measure, only re-select the button
* if it is different to the previously selected one. */
if(best != cur_button) {
- dvdnav_button_select(this, best);
+ dvdnav_button_select(this, pci, best);
}
}
return S_OK;
}
-dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, int x, int y) {
+dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int x, int y) {
/* A trivial function */
- if(dvdnav_mouse_select(this, x,y) != S_ERR) {
- return dvdnav_button_activate(this);
+ if(dvdnav_mouse_select(this, pci, x,y) != S_ERR) {
+ return dvdnav_button_activate(this, pci);
}
/* Should never get here without an error */
diff --git a/src/input/libdvdnav/navigation.c b/src/input/libdvdnav/navigation.c
index 748cb7f52..a3a26dd7d 100644
--- a/src/input/libdvdnav/navigation.c
+++ b/src/input/libdvdnav/navigation.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: navigation.c,v 1.2 2002/09/04 11:07:47 mroi Exp $
+ * $Id: navigation.c,v 1.3 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -51,23 +51,34 @@ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int *titles) {
return S_ERR;
}
+ if(!this->started) {
+ /* Start the VM */
+ vm_start(this->vm);
+ this->started = 1;
+ }
+
(*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts;
return S_OK;
}
-/* This function should not be used. FIXME: Suggest alternative */
-dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *this, int *programs) {
+dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int title, int *parts) {
if(!this)
return S_ERR;
- if(!programs) {
+ if(!parts) {
printerr("Passed a NULL pointer");
return S_ERR;
}
-
- (*programs) = this->vm->state.pgc->nr_of_programs;
-
+ if(!this->started) {
+ printerr("Virtual DVD machine not started.");
+ return S_ERR;
+ }
+ if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) {
+ printerr("Passed a title number out of range");
+ return S_ERR;
+ }
+ (*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts;
return S_OK;
}
diff --git a/src/input/libdvdnav/remap.c b/src/input/libdvdnav/remap.c
new file mode 100644
index 000000000..ca30287c6
--- /dev/null
+++ b/src/input/libdvdnav/remap.c
@@ -0,0 +1,225 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/fcntl.h>
+#include <assert.h>
+#include "remap.h"
+
+struct block_s {
+ int domain;
+ int title;
+ int program;
+ unsigned long start_block;
+ unsigned long end_block;
+};
+
+struct remap_s {
+ char *title;
+ int maxblocks;
+ int nblocks;
+ int debug;
+ struct block_s *blocks;
+};
+
+remap_t* remap_new( char *title) {
+ remap_t *map = malloc( sizeof(remap_t));
+ map->title = strdup(title);
+ map->maxblocks = 0;
+ map->nblocks = 0;
+ map->blocks = NULL;
+ map->debug = 0;
+ return map;
+}
+
+static int compare_block( block_t *a, block_t *b) {
+ /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
+ if (a->domain < b->domain) {
+ return -1;
+ } else if (a->domain > b->domain) {
+ return 1;
+ }
+
+ if (a->title < b->title) {
+ return -1;
+ } else if (a->title > b->title) {
+ return 1;
+ }
+
+ if (a->program < b->program) {
+ return -1;
+ } else if (a->program > b->program) {
+ return 1;
+ }
+
+ if (a->end_block < b->start_block) {
+ return -1;
+ } else if (a->start_block > b->end_block) {
+ /*
+ * if a->start_block == b->end_block then the two regions
+ * aren't strictly overlapping, but they should be merged
+ * anyway since there are zero blocks between them
+ */
+ return 1;
+ }
+
+ return 0;
+}
+
+static block_t *findblock( remap_t *map, block_t *key) {
+ int lb = 0;
+ int ub = map->nblocks - 1;
+ int mid;
+ int res;
+
+ while (lb <= ub) {
+ mid = lb + (ub - lb)/2;
+ res = compare_block( key, &map->blocks[mid]);
+ if (res < 0) {
+ ub = mid-1;
+ } else if (res > 0) {
+ lb = mid+1;
+ } else {
+ return &map->blocks[mid];
+ }
+ }
+ return NULL;
+}
+
+static void mergeblock( block_t *b, block_t tmp) {
+ if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;
+ if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;
+}
+
+static void remap_add_node( remap_t *map, block_t block) {
+ block_t *b;
+ int n;
+ b = findblock( map, &block);
+ if (b) {
+ /* overlaps an existing block */
+ mergeblock( b, block);
+ } else {
+ /* new block */
+ if (map->nblocks >= map->maxblocks) {
+ map->maxblocks += 20;
+ map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
+ }
+ n = map->nblocks++;
+ while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
+ map->blocks[ n] = map->blocks[ n-1];
+ n--;
+ }
+ map->blocks[ n] = block;
+ }
+}
+
+int parseblock(
+ char *buf, int *dom, int *tt, int *pg,
+ unsigned long *start, unsigned long *end)
+{
+ long tmp;
+ char *tok;
+ char *epos;
+ char *marker[]={"domain", "title", "program", "start", "end"};
+ int st = 0;
+ tok = strtok( buf, " ");
+ while (st < 5) {
+ if (strcmp(tok, marker[st])) return -st-1000;
+ tok = strtok( NULL, " ");
+ if (!tok) return -st-2000;
+ tmp = strtol( tok, &epos, 0);
+ if (*epos != 0 && *epos != ',') return -st-3000;
+ switch (st) {
+ case 0:
+ *dom = (int)tmp;
+ break;
+ case 1:
+ *tt = (int)tmp;
+ break;
+ case 2:
+ *pg = (int)tmp;
+ break;
+ case 3:
+ *start = tmp;
+ break;
+ case 4:
+ *end = tmp;
+ break;
+ }
+ st++;
+ tok = strtok( NULL, " ");
+ }
+ return st;
+}
+
+remap_t* remap_loadmap( char *title) {
+ char buf[160];
+ char fname[MAXPATHLEN];
+ char *home;
+ int res;
+ FILE *fp;
+ block_t tmp;
+ remap_t *map;
+
+ /* Build the map filename */
+ home = getenv("HOME"); assert(home);
+ strncpy(fname, home, sizeof(fname));
+ strncat(fname, "/.xine/", sizeof(fname));
+ strncat(fname, title, sizeof(fname));
+ strncat(fname, ".map", sizeof(fname));
+
+ printf("Loading %s.\n", fname);
+ /* Open the map file */
+ fp = fopen( fname, "r");
+ if (!fp) {
+ printf("Unable to find map file '%s'\n", fname);
+ return NULL;
+ }
+
+ /* Load the map file */
+ map = remap_new( title);
+ while (fgets( buf, sizeof(buf), fp) != NULL) {
+ if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
+ if (strncasecmp( buf, "debug", 5) == 0) {
+ map->debug = 1;
+ } else {
+ res = parseblock( buf,
+ &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
+ if (res != 5) {
+ printf("Ignoring map line (%d): %s\n", res, buf);
+ continue;
+ }
+ remap_add_node( map, tmp);
+ }
+ }
+
+ if (map->nblocks == 0 && map->debug == 0) return NULL;
+ return map;
+}
+
+unsigned long remap_block(
+ remap_t *map, int domain, int title, int program,
+ unsigned long cblock, unsigned long offset)
+{
+ block_t key;
+ block_t *b;
+
+ if (map->debug) {
+ printf("%s: domain %d, title %d, program %d, start %lx, next %lx\n",
+ map->title, domain, title, program, cblock, cblock+offset);
+ }
+
+ key.domain = domain;
+ key.title = title;
+ key.program = program;
+ key.start_block = key.end_block = cblock + offset;
+ b = findblock( map, &key);
+
+ if (b) {
+ if (map->debug) {
+ printf("Redirected to %lx\n", b->end_block);
+ }
+ return b->end_block - cblock;
+ }
+ return offset;
+}
diff --git a/src/input/libdvdnav/remap.h b/src/input/libdvdnav/remap.h
new file mode 100644
index 000000000..841a24a51
--- /dev/null
+++ b/src/input/libdvdnav/remap.h
@@ -0,0 +1,13 @@
+#ifndef __REMAP__H
+#define __REMAP__H
+typedef struct block_s block_t;
+
+typedef struct remap_s remap_t;
+
+remap_t* remap_loadmap( char *title);
+
+unsigned long remap_block(
+ remap_t *map, int domain, int title, int program,
+ unsigned long cblock, unsigned long offset);
+
+#endif
diff --git a/src/input/libdvdnav/settings.c b/src/input/libdvdnav/settings.c
index a9a5df45e..c74eda500 100644
--- a/src/input/libdvdnav/settings.c
+++ b/src/input/libdvdnav/settings.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: settings.c,v 1.1 2002/08/08 17:49:21 richwareham Exp $
+ * $Id: settings.c,v 1.2 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -33,11 +33,13 @@
/* Characteristics/setting API calls */
dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int *region) {
- if(!this)
- return S_ERR;
+ if(!this) {
+ printerr("Passed a NULL this pointer");
+ return S_ERR;
+ }
if(!region) {
- printerr("Passed a NULL pointer");
+ printerr("Passed a NULL region pointer");
return S_ERR;
}
@@ -75,11 +77,13 @@ dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int use_readahead) {
}
dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int* flag) {
- if(!this)
- return S_ERR;
+ if(!this) {
+ printerr("Passed a NULL this pointer");
+ return S_ERR;
+ }
if(!flag) {
- printerr("Passed a NULL pointer");
+ printerr("Passed a NULL flag pointer");
return S_ERR;
}
@@ -88,9 +92,16 @@ dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int* flag) {
}
static dvdnav_status_t set_language_register(dvdnav_t *this, char *code, int reg) {
- if(!this)
+ if(!this ) {
+ printerr("Passed a NULL this pointer");
return S_ERR;
+ }
+ if(!code) {
+ printerr("Passed a NULL code pointer");
+ return S_ERR;
+ }
+
if(!code[0] || !code[1]) {
printerr("Passed illegal language code");
return S_ERR;
diff --git a/src/input/libdvdnav/vm.c b/src/input/libdvdnav/vm.c
index 10b9f9f32..2a21a8499 100644
--- a/src/input/libdvdnav/vm.c
+++ b/src/input/libdvdnav/vm.c
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: vm.c,v 1.5 2002/09/04 11:07:47 mroi Exp $
+ * $Id: vm.c,v 1.6 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -33,6 +33,9 @@
#include <unistd.h>
#include <inttypes.h>
#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "ifo_types.h"
#include "ifo_read.h"
@@ -173,6 +176,63 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
return vm->dvd;
}
+void dvd_read_name( vm_t *this, char *devname) {
+ int fd, i;
+ off64_t off;
+ uint8_t data[DVD_VIDEO_LB_LEN];
+
+ /* Read DVD name */
+ fd=open(devname, O_RDONLY);
+ if (fd > 0) {
+ off = lseek64( fd, 32 * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET );
+ if( off == ( 32 * (int64_t) DVD_VIDEO_LB_LEN ) ) {
+ off = read( fd, data, DVD_VIDEO_LB_LEN );
+ close(fd);
+ if (off == ( (int64_t) DVD_VIDEO_LB_LEN )) {
+ fprintf( stderr, "VM DVD Title: ");
+ for(i=25; i < 73; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(stderr, "%c", data[i]);
+ } else {
+ fprintf(stderr, " ");
+ }
+ }
+ strncpy(&this->dvd_name[0], &data[25], 48);
+ /* fprintf(stderr, "TITLE:%s\n",&this->dvd_name[0]); */
+ this->dvd_name[48]=0;
+ this->dvd_name_length=strlen(&this->dvd_name[0]);
+ fprintf( stderr, "\nVM DVD Serial Number: ");
+ for(i=73; i < 89; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(stderr, "%c", data[i]);
+ } else {
+ fprintf(stderr, " ");
+ }
+ }
+ fprintf( stderr, "\nVM DVD Title (Alternative): ");
+ for(i=89; i < 128; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(stderr, "%c", data[i]);
+ } else {
+ fprintf(stderr, " ");
+ }
+ }
+ fprintf( stderr, "\n");
+ } else {
+ fprintf( stderr, "libdvdread: Can't read name block. Probably not a DVD-ROM device.\n");
+ }
+ } else {
+ fprintf( stderr, "libdvdread: Can't seek to block %u\n", 32 );
+ }
+ close(fd);
+ } else {
+ fprintf(stderr,"NAME OPEN FAILED\n");
+ }
+}
+
int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ {
/* Setup State */
memset((vm->state).registers.SPRM, 0, sizeof(uint16_t)*24);
@@ -222,6 +282,8 @@ int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ {
fprintf(MSG_OUT, "libdvdnav: vm: faild to open/read the DVD\n");
return -1;
}
+ dvd_read_name(vm, dvdroot);
+ vm->map = remap_loadmap( vm->dvd_name);
vm->vmgi = ifoOpenVMGI(vm->dvd);
if(!vm->vmgi) {
@@ -1926,6 +1988,9 @@ static pgcit_t* get_PGCIT(vm_t *vm) {
/*
* $Log: vm.c,v $
+ * Revision 1.6 2002/09/20 12:53:53 mroi
+ * sync to latest libdvdnav cvs version
+ *
* Revision 1.5 2002/09/04 11:07:47 mroi
* sync to libdvdnav cvs
*
diff --git a/src/input/libdvdnav/vm.h b/src/input/libdvdnav/vm.h
index 99da87a73..e4c6f1863 100644
--- a/src/input/libdvdnav/vm.h
+++ b/src/input/libdvdnav/vm.h
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: vm.h,v 1.2 2002/09/04 11:07:47 mroi Exp $
+ * $Id: vm.h,v 1.3 2002/09/20 12:53:53 mroi Exp $
*
*/
@@ -27,6 +27,7 @@
#define VM_H_INCLUDED
#include "decoder.h"
+#include "remap.h"
#include <dvd_types.h>
/* DOMAIN enum */
@@ -87,6 +88,9 @@ typedef struct {
dvd_state_t state;
int badness_counter;
int32_t hop_channel;
+ char dvd_name[50];
+ int dvd_name_length;
+ remap_t *map;
} vm_t;