comparison highlight.c @ 114:b6834e6359cf src

big libdvdnav cleanup, quoting the ChangeLog: * some bugfixes * code cleanup * build process polishing * more sensible event order in get_next_block to ensure useful event delivery * VOBU level resume * fixed: seeking in a multiangle feature briefly showed the wrong angle
author mroi
date Thu, 20 Feb 2003 15:32:21 +0000
parents 457f35f43ba6
children 4d711d0518e9
comparison
equal deleted inserted replaced
113:ec2df154be56 114:b6834e6359cf
23 23
24 #ifdef HAVE_CONFIG_H 24 #ifdef HAVE_CONFIG_H
25 #include "config.h" 25 #include "config.h"
26 #endif 26 #endif
27 27
28
29 #define BUTTON_TESTING
30
31 #include <assert.h> 28 #include <assert.h>
32 29
33 #include <dvdnav.h>
34 #include "dvdnav_internal.h" 30 #include "dvdnav_internal.h"
35 31
36 #include "vm.h" 32 #include "vm.h"
37 #include <dvdread/nav_types.h> 33 #include <dvdread/nav_types.h>
38 34
39 #ifdef BUTTON_TESTING 35 /*
36 #define BUTTON_TESTING
37 */
38
39 #ifdef BUTTON_TESTING
40
40 #include <dvdread/nav_print.h> 41 #include <dvdread/nav_print.h>
41 #include "vmcmd.h" 42 #include "vmcmd.h"
42 43
43 static void print_time(dvd_time_t *dtime) { 44 static void print_time(dvd_time_t *dtime) {
44 const char *rate; 45 const char *rate;
46
45 assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa); 47 assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
46 assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa); 48 assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
47 assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa); 49 assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
48 assert((dtime->frame_u&0xf) < 0xa); 50 assert((dtime->frame_u&0xf) < 0xa);
49 51
67 } 69 }
68 70
69 static void nav_print_PCI_GI(pci_gi_t *pci_gi) { 71 static void nav_print_PCI_GI(pci_gi_t *pci_gi) {
70 int i; 72 int i;
71 73
72 fprintf(MSG_OUT,"pci_gi:\n"); 74 fprintf(MSG_OUT,"libdvdnav: pci_gi:\n");
73 fprintf(MSG_OUT,"nv_pck_lbn 0x%08x\n", pci_gi->nv_pck_lbn); 75 fprintf(MSG_OUT,"libdvdnav: nv_pck_lbn 0x%08x\n", pci_gi->nv_pck_lbn);
74 fprintf(MSG_OUT,"vobu_cat 0x%04x\n", pci_gi->vobu_cat); 76 fprintf(MSG_OUT,"libdvdnav: vobu_cat 0x%04x\n", pci_gi->vobu_cat);
75 fprintf(MSG_OUT,"vobu_uop_ctl 0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl); 77 fprintf(MSG_OUT,"libdvdnav: vobu_uop_ctl 0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl);
76 fprintf(MSG_OUT,"vobu_s_ptm 0x%08x\n", pci_gi->vobu_s_ptm); 78 fprintf(MSG_OUT,"libdvdnav: vobu_s_ptm 0x%08x\n", pci_gi->vobu_s_ptm);
77 fprintf(MSG_OUT,"vobu_e_ptm 0x%08x\n", pci_gi->vobu_e_ptm); 79 fprintf(MSG_OUT,"libdvdnav: vobu_e_ptm 0x%08x\n", pci_gi->vobu_e_ptm);
78 fprintf(MSG_OUT,"vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm); 80 fprintf(MSG_OUT,"libdvdnav: vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm);
79 fprintf(MSG_OUT,"e_eltm "); 81 fprintf(MSG_OUT,"libdvdnav: e_eltm ");
80 print_time(&pci_gi->e_eltm); 82 print_time(&pci_gi->e_eltm);
81 fprintf(MSG_OUT,"\n"); 83 fprintf(MSG_OUT,"\n");
82 84
83 fprintf(MSG_OUT,"vobu_isrc \""); 85 fprintf(MSG_OUT,"libdvdnav: vobu_isrc \"");
84 for(i = 0; i < 32; i++) { 86 for(i = 0; i < 32; i++) {
85 char c = pci_gi->vobu_isrc[i]; 87 char c = pci_gi->vobu_isrc[i];
86 if((c >= ' ') && (c <= '~')) 88 if((c >= ' ') && (c <= '~'))
87 fprintf(MSG_OUT,"%c", c); 89 fprintf(MSG_OUT,"%c", c);
88 else 90 else
97 for(i = 0; i < 9; i++) 99 for(i = 0; i < 9; i++)
98 j |= nsml_agli->nsml_agl_dsta[i]; 100 j |= nsml_agli->nsml_agl_dsta[i];
99 if(j == 0) 101 if(j == 0)
100 return; 102 return;
101 103
102 fprintf(MSG_OUT,"nsml_agli:\n"); 104 fprintf(MSG_OUT,"libdvdnav: nsml_agli:\n");
103 for(i = 0; i < 9; i++) 105 for(i = 0; i < 9; i++)
104 if(nsml_agli->nsml_agl_dsta[i]) 106 if(nsml_agli->nsml_agl_dsta[i])
105 fprintf(MSG_OUT,"nsml_agl_c%d_dsta 0x%08x\n", i + 1, 107 fprintf(MSG_OUT,"libdvdnav: nsml_agl_c%d_dsta 0x%08x\n", i + 1,
106 nsml_agli->nsml_agl_dsta[i]); 108 nsml_agli->nsml_agl_dsta[i]);
107 } 109 }
108 110
109 static void nav_print_HL_GI(hl_gi_t *hl_gi, int *btngr_ns, int *btn_ns) { 111 static void nav_print_HL_GI(hl_gi_t *hl_gi, int *btngr_ns, int *btn_ns) {
110 112
111 if((hl_gi->hli_ss & 0x03) == 0) 113 if((hl_gi->hli_ss & 0x03) == 0)
112 return; 114 return;
113 115
114 fprintf(MSG_OUT,"hl_gi:\n"); 116 fprintf(MSG_OUT,"libdvdnav: hl_gi:\n");
115 fprintf(MSG_OUT,"hli_ss 0x%01x\n", hl_gi->hli_ss & 0x03); 117 fprintf(MSG_OUT,"libdvdnav: hli_ss 0x%01x\n", hl_gi->hli_ss & 0x03);
116 fprintf(MSG_OUT,"hli_s_ptm 0x%08x\n", hl_gi->hli_s_ptm); 118 fprintf(MSG_OUT,"libdvdnav: hli_s_ptm 0x%08x\n", hl_gi->hli_s_ptm);
117 fprintf(MSG_OUT,"hli_e_ptm 0x%08x\n", hl_gi->hli_e_ptm); 119 fprintf(MSG_OUT,"libdvdnav: hli_e_ptm 0x%08x\n", hl_gi->hli_e_ptm);
118 fprintf(MSG_OUT,"btn_se_e_ptm 0x%08x\n", hl_gi->btn_se_e_ptm); 120 fprintf(MSG_OUT,"libdvdnav: btn_se_e_ptm 0x%08x\n", hl_gi->btn_se_e_ptm);
119 121
120 *btngr_ns = hl_gi->btngr_ns; 122 *btngr_ns = hl_gi->btngr_ns;
121 fprintf(MSG_OUT,"btngr_ns %d\n", hl_gi->btngr_ns); 123 fprintf(MSG_OUT,"libdvdnav: btngr_ns %d\n", hl_gi->btngr_ns);
122 fprintf(MSG_OUT,"btngr%d_dsp_ty 0x%02x\n", 1, hl_gi->btngr1_dsp_ty); 124 fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 1, hl_gi->btngr1_dsp_ty);
123 fprintf(MSG_OUT,"btngr%d_dsp_ty 0x%02x\n", 2, hl_gi->btngr2_dsp_ty); 125 fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 2, hl_gi->btngr2_dsp_ty);
124 fprintf(MSG_OUT,"btngr%d_dsp_ty 0x%02x\n", 3, hl_gi->btngr3_dsp_ty); 126 fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 3, hl_gi->btngr3_dsp_ty);
125 127
126 fprintf(MSG_OUT,"btn_ofn %d\n", hl_gi->btn_ofn); 128 fprintf(MSG_OUT,"libdvdnav: btn_ofn %d\n", hl_gi->btn_ofn);
127 *btn_ns = hl_gi->btn_ns; 129 *btn_ns = hl_gi->btn_ns;
128 fprintf(MSG_OUT,"btn_ns %d\n", hl_gi->btn_ns); 130 fprintf(MSG_OUT,"libdvdnav: btn_ns %d\n", hl_gi->btn_ns);
129 fprintf(MSG_OUT,"nsl_btn_ns %d\n", hl_gi->nsl_btn_ns); 131 fprintf(MSG_OUT,"libdvdnav: nsl_btn_ns %d\n", hl_gi->nsl_btn_ns);
130 fprintf(MSG_OUT,"fosl_btnn %d\n", hl_gi->fosl_btnn); 132 fprintf(MSG_OUT,"libdvdnav: fosl_btnn %d\n", hl_gi->fosl_btnn);
131 fprintf(MSG_OUT,"foac_btnn %d\n", hl_gi->foac_btnn); 133 fprintf(MSG_OUT,"libdvdnav: foac_btnn %d\n", hl_gi->foac_btnn);
132 } 134 }
133 135
134 static void nav_print_BTN_COLIT(btn_colit_t *btn_colit) { 136 static void nav_print_BTN_COLIT(btn_colit_t *btn_colit) {
135 int i, j; 137 int i, j;
136 138
138 for(i = 0; i < 6; i++) 140 for(i = 0; i < 6; i++)
139 j |= btn_colit->btn_coli[i/2][i&1]; 141 j |= btn_colit->btn_coli[i/2][i&1];
140 if(j == 0) 142 if(j == 0)
141 return; 143 return;
142 144
143 fprintf(MSG_OUT,"btn_colit:\n"); 145 fprintf(MSG_OUT,"libdvdnav: btn_colit:\n");
144 for(i = 0; i < 3; i++) 146 for(i = 0; i < 3; i++)
145 for(j = 0; j < 2; j++) 147 for(j = 0; j < 2; j++)
146 fprintf(MSG_OUT,"btn_cqoli %d %s_coli: %08x\n", 148 fprintf(MSG_OUT,"libdvdnav: btn_cqoli %d %s_coli: %08x\n",
147 i, (j == 0) ? "sl" : "ac", 149 i, (j == 0) ? "sl" : "ac",
148 btn_colit->btn_coli[i][j]); 150 btn_colit->btn_coli[i][j]);
149 } 151 }
150 152
151 static void nav_print_BTNIT(btni_t *btni_table, int btngr_ns, int btn_ns) { 153 static void nav_print_BTNIT(btni_t *btni_table, int btngr_ns, int btn_ns) {
152 int i, j, k; 154 int i, j, k;
153 155
154 fprintf(MSG_OUT,"btnit:\n"); 156 fprintf(MSG_OUT,"libdvdnav: btnit:\n");
155 fprintf(MSG_OUT,"btngr_ns: %i\n", btngr_ns); 157 fprintf(MSG_OUT,"libdvdnav: btngr_ns: %i\n", btngr_ns);
156 fprintf(MSG_OUT,"btn_ns: %i\n", btn_ns); 158 fprintf(MSG_OUT,"libdvdnav: btn_ns: %i\n", btn_ns);
157 159
158 if(btngr_ns == 0) 160 if(btngr_ns == 0)
159 return; 161 return;
160 162
161 for(i = 0; i < btngr_ns; i++) { 163 for(i = 0; i < btngr_ns; i++) {
162 for(j = 0; j < (36 / btngr_ns); j++) { 164 for(j = 0; j < (36 / btngr_ns); j++) {
163 if(j < btn_ns) { 165 if(j < btn_ns) {
164 btni_t *btni = &btni_table[(36 / btngr_ns) * i + j]; 166 btni_t *btni = &btni_table[(36 / btngr_ns) * i + j];
165 167
166 fprintf(MSG_OUT,"group %d btni %d: ", i+1, j+1); 168 fprintf(MSG_OUT,"libdvdnav: group %d btni %d: ", i+1, j+1);
167 fprintf(MSG_OUT,"btn_coln %d, auto_action_mode %d\n", 169 fprintf(MSG_OUT,"btn_coln %d, auto_action_mode %d\n",
168 btni->btn_coln, btni->auto_action_mode); 170 btni->btn_coln, btni->auto_action_mode);
169 fprintf(MSG_OUT,"coords (%d, %d) .. (%d, %d)\n", 171 fprintf(MSG_OUT,"libdvdnav: coords (%d, %d) .. (%d, %d)\n",
170 btni->x_start, btni->y_start, btni->x_end, btni->y_end); 172 btni->x_start, btni->y_start, btni->x_end, btni->y_end);
171 173
172 fprintf(MSG_OUT,"up %d, ", btni->up); 174 fprintf(MSG_OUT,"libdvdnav: up %d, ", btni->up);
173 fprintf(MSG_OUT,"down %d, ", btni->down); 175 fprintf(MSG_OUT,"down %d, ", btni->down);
174 fprintf(MSG_OUT,"left %d, ", btni->left); 176 fprintf(MSG_OUT,"left %d, ", btni->left);
175 fprintf(MSG_OUT,"right %d\n", btni->right); 177 fprintf(MSG_OUT,"right %d\n", btni->right);
176 for(k = 0; k < 8; k++) { 178 for(k = 0; k < 8; k++) {
177 fprintf(MSG_OUT, "%02x ", btni->cmd.bytes[k]); 179 fprintf(MSG_OUT, "libdvdnav: %02x ", btni->cmd.bytes[k]);
178 } 180 }
179 fprintf(MSG_OUT, "| "); 181 fprintf(MSG_OUT, "| ");
180 vmPrint_mnemonic(&btni->cmd); 182 vmPrint_mnemonic(&btni->cmd);
181 fprintf(MSG_OUT, "\n\n"); 183 fprintf(MSG_OUT, "\n");
182 } 184 }
183 } 185 }
184 } 186 }
185 } 187 }
186 188
187 static void nav_print_HLI(hli_t *hli) { 189 static void nav_print_HLI(hli_t *hli) {
188 int btngr_ns = 0, btn_ns = 0; 190 int btngr_ns = 0, btn_ns = 0;
189 191
190 fprintf(MSG_OUT,"hli:\n"); 192 fprintf(MSG_OUT,"libdvdnav: hli:\n");
191 nav_print_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns); 193 nav_print_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns);
192 nav_print_BTN_COLIT(&hli->btn_colit); 194 nav_print_BTN_COLIT(&hli->btn_colit);
193 nav_print_BTNIT(hli->btnit, btngr_ns, btn_ns); 195 nav_print_BTNIT(hli->btnit, btngr_ns, btn_ns);
194 } 196 }
195 197
196 void nav_print_PCI(pci_t *pci) { 198 void nav_print_PCI(pci_t *pci) {
197 fprintf(MSG_OUT,"pci packet:\n"); 199 fprintf(MSG_OUT,"libdvdnav: pci packet:\n");
198 nav_print_PCI_GI(&pci->pci_gi); 200 nav_print_PCI_GI(&pci->pci_gi);
199 nav_print_NSML_AGLI(&pci->nsml_agli); 201 nav_print_NSML_AGLI(&pci->nsml_agli);
200 nav_print_HLI(&pci->hli); 202 nav_print_HLI(&pci->hli);
201 } 203 }
202 204
203 205 #endif
204 #endif 206
205 207
206 /* Highlighting API calls */ 208 /* Highlighting API calls */
207 209
208 210 dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int *button) {
209 211
210 dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int* button) { 212 if(!this) {
211 if(!this) 213 printerr("Passed a NULL pointer.");
212 return S_ERR; 214 return S_ERR;
215 }
213 216
214 /* Simply return the appropriate value based on the SPRM */ 217 /* Simply return the appropriate value based on the SPRM */
215 (*button) = (this->vm->state.HL_BTNN_REG) >> 10; 218 (*button) = (this->vm->state.HL_BTNN_REG) >> 10;
216 219
217 return S_OK; 220 return S_OK;
218 } 221 }
219 222
220 btni_t *__get_current_button(dvdnav_t *this, pci_t *pci) { 223 static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) {
221 int button = 0; 224 int button = 0;
222 225
223 if(dvdnav_get_current_highlight(this, &button) != S_OK) { 226 if(dvdnav_get_current_highlight(this, &button) != S_OK) {
224 printerr("Unable to get information on current highlight."); 227 printerr("Unable to get information on current highlight.");
225 return NULL; 228 return NULL;
229 #endif 232 #endif
230 233
231 return &(pci->hli.btnit[button-1]); 234 return &(pci->hli.btnit[button-1]);
232 } 235 }
233 236
234 dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this, pci_t *pci) { 237 static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) {
235 btni_t *button_ptr; 238 if (get_current_button(this, pci)->auto_action_mode)
236 239 return dvdnav_button_activate(this, pci);
237 if(!this) 240 }
238 return S_ERR;
239
240 if((button_ptr = __get_current_button(this, pci)) == NULL) {
241 return S_ERR;
242 }
243 if (button_ptr->auto_action_mode == 1) {
244 return S_OK;
245 }
246 return S_ERR;
247 }
248
249 241
250 dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) { 242 dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) {
251 btni_t *button_ptr; 243 btni_t *button_ptr;
252 244
253 if(!this) 245 if(!this) {
254 return S_ERR; 246 printerr("Passed a NULL pointer.");
255 247 return S_ERR;
256 if((button_ptr = __get_current_button(this, pci)) == NULL) { 248 }
257 return S_ERR; 249
258 } 250 if(!(button_ptr = get_current_button(this, pci)))
251 return S_ERR;
259 252
260 dvdnav_button_select(this, pci, button_ptr->up); 253 dvdnav_button_select(this, pci, button_ptr->up);
261 if (dvdnav_button_auto_action(this, pci) ) { 254 button_auto_action(this, pci);
262 dvdnav_button_activate(this, pci);
263 }
264 255
265 return S_OK; 256 return S_OK;
266 } 257 }
267 258
268 dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) { 259 dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) {
269 btni_t *button_ptr; 260 btni_t *button_ptr;
270 261
271 if(!this) 262 if(!this) {
272 return S_ERR; 263 printerr("Passed a NULL pointer.");
273 264 return S_ERR;
274 if((button_ptr = __get_current_button(this, pci)) == NULL) { 265 }
275 return S_ERR; 266
276 } 267 if(!(button_ptr = get_current_button(this, pci)))
268 return S_ERR;
277 269
278 dvdnav_button_select(this, pci, button_ptr->down); 270 dvdnav_button_select(this, pci, button_ptr->down);
279 if (dvdnav_button_auto_action(this, pci) ) { 271 button_auto_action(this, pci);
280 dvdnav_button_activate(this, pci);
281 }
282 272
283 return S_OK; 273 return S_OK;
284 } 274 }
285 275
286 dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) { 276 dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) {
287 btni_t *button_ptr; 277 btni_t *button_ptr;
288 278
289 if(!this) 279 if(!this) {
290 return S_ERR; 280 printerr("Passed a NULL pointer.");
291 281 return S_ERR;
292 if((button_ptr = __get_current_button(this, pci)) == NULL) { 282 }
293 printerr("Error fetching information on current button."); 283
294 return S_ERR; 284 if(!(button_ptr = get_current_button(this, pci)))
295 } 285 return S_ERR;
296 286
297 dvdnav_button_select(this, pci, button_ptr->right); 287 dvdnav_button_select(this, pci, button_ptr->right);
298 if (dvdnav_button_auto_action(this, pci) ) { 288 button_auto_action(this, pci);
299 dvdnav_button_activate(this, pci);
300 }
301 289
302 return S_OK; 290 return S_OK;
303 } 291 }
304 292
305 dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) { 293 dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) {
306 btni_t *button_ptr; 294 btni_t *button_ptr;
307 295
308 if(!this) 296 if(!this) {
309 return S_ERR; 297 printerr("Passed a NULL pointer.");
310 298 return S_ERR;
311 if((button_ptr = __get_current_button(this, pci)) == NULL) { 299 }
312 return S_ERR; 300
313 } 301 if(!(button_ptr = get_current_button(this, pci)))
302 return S_ERR;
314 303
315 dvdnav_button_select(this, pci, button_ptr->left); 304 dvdnav_button_select(this, pci, button_ptr->left);
316 if (dvdnav_button_auto_action(this, pci) ) { 305 button_auto_action(this, pci);
317 dvdnav_button_activate(this, pci); 306
318 } 307 return S_OK;
319 308 }
320 return S_OK; 309
321 } 310 dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
322 311 dvdnav_highlight_area_t *highlight) {
323 dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32_t mode,
324 dvdnav_highlight_area_t* highlight) {
325 btni_t *button_ptr; 312 btni_t *button_ptr;
313
326 #ifdef BUTTON_TESTING 314 #ifdef BUTTON_TESTING
327 fprintf(MSG_OUT, "libdvdnav: Button get_highlight_area %i\n", button); 315 fprintf(MSG_OUT, "libdvdnav: Button get_highlight_area %i\n", button);
328 #endif 316 #endif
329 317
330 /* Set the highlight SPRM if the passed button was valid*/ 318 if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns))
331 if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) { 319 return S_ERR;
332 fprintf(MSG_OUT, "libdvdnav: Unable to select button number %i as it doesn't exist\n", 320
333 button);
334 return S_ERR;
335 }
336 button_ptr = &nav_pci->hli.btnit[button-1]; 321 button_ptr = &nav_pci->hli.btnit[button-1];
337 322
338 highlight->sx = button_ptr->x_start; 323 highlight->sx = button_ptr->x_start;
339 highlight->sy = button_ptr->y_start; 324 highlight->sy = button_ptr->y_start;
340 highlight->ex = button_ptr->x_end; 325 highlight->ex = button_ptr->x_end;
345 highlight->palette = 0; 330 highlight->palette = 0;
346 } 331 }
347 highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm; 332 highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm;
348 highlight->buttonN = button; 333 highlight->buttonN = button;
349 #ifdef BUTTON_TESTING 334 #ifdef BUTTON_TESTING
350 fprintf(MSG_OUT, "libdvdnav: highlight.c:Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n", 335 fprintf(MSG_OUT, "libdvdnav: highlight: Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n",
351 button_ptr->x_start, button_ptr->y_start, 336 button_ptr->x_start, button_ptr->y_start,
352 button_ptr->x_end, button_ptr->y_end, 337 button_ptr->x_end, button_ptr->y_end,
353 1, 338 1,
354 button); 339 button);
355 #endif 340 #endif
358 } 343 }
359 344
360 dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) { 345 dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
361 int button; 346 int button;
362 btni_t *button_ptr = NULL; 347 btni_t *button_ptr = NULL;
363 348
364 if(!this) 349 if(!this) {
365 return S_ERR; 350 printerr("Passed a NULL pointer.");
351 return S_ERR;
352 }
353
366 pthread_mutex_lock(&this->vm_lock); 354 pthread_mutex_lock(&this->vm_lock);
367 355
368 /* Precisely the same as selecting a button except we want
369 * a different palette */
370 if(dvdnav_get_current_highlight(this, &button) != S_OK) { 356 if(dvdnav_get_current_highlight(this, &button) != S_OK) {
371 pthread_mutex_unlock(&this->vm_lock); 357 pthread_mutex_unlock(&this->vm_lock);
372 return S_ERR; 358 return S_ERR;
373 } 359 }
374 /* FIXME: dvdnav_button_select should really return a 360
375 * special case for explicit NO-BUTTONS. 361 if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
376 */
377 if(dvdnav_button_select(this, pci, button) != S_OK) {
378 /* Special code to handle still menus with no buttons. 362 /* Special code to handle still menus with no buttons.
379 * the navigation is expected to report to the appicatino that a STILL is 363 * the navigation is expected to report to the appicatino that a STILL is
380 * underway. In turn, the application is supposed to report to the user 364 * underway. In turn, the application is supposed to report to the user
381 * that the playback is pause. The user is then expected to undo the pause. 365 * that the playback is pause. The user is then expected to undo the pause.
382 * ie: hit play. At that point, the navigation should release the still and 366 * ie: hit play. At that point, the navigation should release the still and
387 if (this->position_current.still != 0) { 371 if (this->position_current.still != 0) {
388 /* In still, but no buttons. */ 372 /* In still, but no buttons. */
389 vm_get_next_cell(this->vm); 373 vm_get_next_cell(this->vm);
390 this->position_current.still = 0; 374 this->position_current.still = 0;
391 pthread_mutex_unlock(&this->vm_lock); 375 pthread_mutex_unlock(&this->vm_lock);
376 /* clear error message */
377 printerr("");
392 return S_OK; 378 return S_OK;
393 } 379 }
394 pthread_mutex_unlock(&this->vm_lock); 380 pthread_mutex_unlock(&this->vm_lock);
395 return S_ERR; 381 return S_ERR;
396 } 382 }
397 /* FIXME: The button command should really be passed in the API instead. */ 383
398 button_ptr = __get_current_button(this, pci); 384 button_ptr = get_current_button(this, pci);
399 /* Finally, make the VM execute the appropriate code and 385 /* Finally, make the VM execute the appropriate code and probably
400 * scedule a jump */ 386 * scedule a jump */
401 #ifdef BUTTON_TESTING 387 #ifdef BUTTON_TESTING
402 fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n"); 388 fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n");
403 #endif 389 #endif
404 if(vm_eval_cmd(this->vm, &(button_ptr->cmd)) == 1) { 390 if(vm_exec_cmd(this->vm, &(button_ptr->cmd)) == 1) {
405 /* Command caused a jump */ 391 /* Command caused a jump */
406 this->vm->hop_channel++; 392 this->vm->hop_channel++;
407 this->position_current.still = 0; 393 this->position_current.still = 0;
408 } 394 }
395
409 pthread_mutex_unlock(&this->vm_lock); 396 pthread_mutex_unlock(&this->vm_lock);
410 return S_OK; 397 return S_OK;
411 } 398 }
412 399
413 dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd) 400 dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd)
414 { 401 {
415 if(!this || !this->vm) 402 if(!this) {
416 return S_ERR; 403 printerr("Passed a NULL pointer.");
417 pthread_mutex_lock(&this->vm_lock); 404 return S_ERR;
418 /* make the VM execute the appropriate code and 405 }
406
407 pthread_mutex_lock(&this->vm_lock);
408 /* make the VM execute the appropriate code and probably
419 * schedule a jump */ 409 * schedule a jump */
420 #ifdef BUTTON_TESTING 410 #ifdef BUTTON_TESTING
421 fprintf(MSG_OUT, "libdvdnav:dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n"); 411 fprintf(MSG_OUT, "libdvdnav: dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n");
422 #endif 412 #endif
423 if(button > 0) { 413 if(button > 0) {
424 printerrf("Select button number %i\n ",
425 button);
426 this->vm->state.HL_BTNN_REG = (button << 10); 414 this->vm->state.HL_BTNN_REG = (button << 10);
427 if( (vm_eval_cmd(this->vm, cmd)) == 1) { 415 if(vm_exec_cmd(this->vm, cmd) == 1) {
428 /* Command caused a jump */ 416 /* Command caused a jump */
429 this->vm->hop_channel++; 417 this->vm->hop_channel++;
430 } 418 }
431 } 419 }
432 /* Always remove still, because some still menus have no buttons. */ 420 /* Always remove still, because some still menus have no buttons. */
436 } 424 }
437 425
438 dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int button) { 426 dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int button) {
439 427
440 if(!this) { 428 if(!this) {
441 printerrf("Unable to select button number %i as this state bad", 429 printerr("Passed a NULL pointer.");
442 button); 430 return S_ERR;
443 return S_ERR;
444 } 431 }
445 432
446 #ifdef BUTTON_TESTING 433 #ifdef BUTTON_TESTING
447 fprintf(MSG_OUT, "libdvdnav: Button select %i\n", button); 434 fprintf(MSG_OUT, "libdvdnav: Button select %i\n", button);
448 #endif 435 #endif
449 436
450 /* Set the highlight SPRM if the passed button was valid*/
451 /* FIXME: this->pci should be provided by the application. */
452 if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) { 437 if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
453 printerrf("Unable to select button number %i as it doesn't exist", 438 printerr("Button does not exist.");
454 button); 439 return S_ERR;
455 return S_ERR; 440 }
456 } 441
457 this->vm->state.HL_BTNN_REG = (button << 10); 442 this->vm->state.HL_BTNN_REG = (button << 10);
458
459 this->hli_state = 1; /* Selected */
460
461 this->position_current.button = -1; /* Force Highligh change */ 443 this->position_current.button = -1; /* Force Highligh change */
462 444
463 return S_OK; 445 return S_OK;
464 } 446 }
465 447
466 dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci, 448 dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci,
467 int button) { 449 int button) {
468 /* A trivial function */ 450 /* A trivial function */
469 if(dvdnav_button_select(this, pci, button) != S_ERR) { 451 if(dvdnav_button_select(this, pci, button) != S_ERR)
470 return dvdnav_button_activate(this, pci); 452 return dvdnav_button_activate(this, pci);
471 }
472
473 /* Should never get here without an error */
474 return S_ERR; 453 return S_ERR;
475 } 454 }
476 455
477 dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int x, int y) { 456 dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int x, int y) {
478 int button, cur_button; 457 int button, cur_button;
479 uint32_t best,dist; 458 uint32_t best,dist;
480 int mx,my,dx,dy,d; 459 int mx,my,dx,dy,d;
481 460
482 /* FIXME: At the moment, the case of no button matchin (x,y) is 461 if(!this) {
483 * silently ignored, is this OK? */ 462 printerr("Passed a NULL pointer.");
484 if(!this) 463 return S_ERR;
485 return S_ERR; 464 }
486 465
487 if(dvdnav_get_current_highlight(this, &cur_button) != S_OK) { 466 if(dvdnav_get_current_highlight(this, &cur_button) != S_OK)
488 return S_ERR; 467 return S_ERR;
489 } 468
490 469 best = 0;
491 best = 0;
492 dist = 0x08000000; /* >> than (720*720)+(567*567); */ 470 dist = 0x08000000; /* >> than (720*720)+(567*567); */
493 471
494 /* Loop through each button */ 472 /* Loop through all buttons */
495 for(button=1; button <= pci->hli.hl_gi.btn_ns; button++) { 473 for(button = 1; button <= pci->hli.hl_gi.btn_ns; button++) {
496 btni_t *button_ptr = NULL; 474 btni_t *button_ptr = &(this->pci.hli.btnit[button-1]);
497 button_ptr = &(this->pci.hli.btnit[button-1]); 475
498 if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) && 476 if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) &&
499 (y >= button_ptr->y_start) && (y <= button_ptr->y_end)) { 477 (y >= button_ptr->y_start) && (y <= button_ptr->y_end)) {
500 mx = (button_ptr->x_start + button_ptr->x_end)/2; 478 mx = (button_ptr->x_start + button_ptr->x_end)/2;
501 my = (button_ptr->y_start + button_ptr->y_end)/2; 479 my = (button_ptr->y_start + button_ptr->y_end)/2;
502 dx = mx - x; 480 dx = mx - x;
503 dy = my - y; 481 dy = my - y;
504 d = (dx*dx) + (dy*dy); 482 d = (dx*dx) + (dy*dy);
505 /* If the mouse is within the button and the mouse is closer 483 /* If the mouse is within the button and the mouse is closer
506 * to the center of this button then it is the best choice. */ 484 * to the center of this button then it is the best choice. */
507 if(d < dist) { 485 if(d < dist) {
508 dist = d; best=button; 486 dist = d;
487 best = button;
509 } 488 }
510 } 489 }
511 } 490 }
512 491
513 if (best!=0) { 492 /* As an efficiency measure, only re-select the button
514 /* As an efficiency measure, only re-select the button 493 * if it is different to the previously selected one. */
515 * if it is different to the previously selected one. */ 494 if (best != 0 && best != cur_button)
516 if(best != cur_button) { 495 dvdnav_button_select(this, pci, best);
517 dvdnav_button_select(this, pci, best); 496
518 } 497 /* return S_OK only if we actually found a matching button */
519 } 498 return best ? S_OK : S_ERR;
520
521 return S_OK;
522 } 499 }
523 500
524 dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int x, int y) { 501 dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int x, int y) {
525 /* A trivial function */ 502 /* A trivial function */
526 if(dvdnav_mouse_select(this, pci, x,y) != S_ERR) { 503 if(dvdnav_mouse_select(this, pci, x,y) != S_ERR)
527 return dvdnav_button_activate(this, pci); 504 return dvdnav_button_activate(this, pci);
528 }
529
530 /* Should never get here without an error */
531 return S_ERR; 505 return S_ERR;
532 } 506 }
533