+void demux_sys_t::StartUiThread()
+{
+ if ( !b_ui_hooked )
+ {
+ msg_Dbg( &demuxer, "Starting the UI Hook" );
+ b_ui_hooked = true;
+ /* FIXME hack hack hack hack FIXME */
+ /* Get p_input and create variable */
+ p_input = (input_thread_t *) vlc_object_find( &demuxer, VLC_OBJECT_INPUT, FIND_PARENT );
+ var_Create( p_input, "x-start", VLC_VAR_INTEGER );
+ var_Create( p_input, "y-start", VLC_VAR_INTEGER );
+ var_Create( p_input, "x-end", VLC_VAR_INTEGER );
+ var_Create( p_input, "y-end", VLC_VAR_INTEGER );
+ var_Create( p_input, "color", VLC_VAR_ADDRESS );
+ var_Create( p_input, "menu-palette", VLC_VAR_ADDRESS );
+ var_Create( p_input, "highlight", VLC_VAR_BOOL );
+ var_Create( p_input, "highlight-mutex", VLC_VAR_MUTEX );
+
+ /* Now create our event thread catcher */
+ p_ev = (event_thread_t *) vlc_object_create( &demuxer, sizeof( event_thread_t ) );
+ p_ev->p_demux = &demuxer;
+ p_ev->b_die = VLC_FALSE;
+ vlc_mutex_init( p_ev, &p_ev->lock );
+ vlc_thread_create( p_ev, "mkv event thread handler", EventThread,
+ VLC_THREAD_PRIORITY_LOW, VLC_FALSE );
+ }
+}
+
+void demux_sys_t::StopUiThread()
+{
+ if ( b_ui_hooked )
+ {
+ vlc_object_kill( p_ev );
+ vlc_thread_join( p_ev );
+ vlc_object_destroy( p_ev );
+
+ p_ev = NULL;
+
+ var_Destroy( p_input, "highlight-mutex" );
+ var_Destroy( p_input, "highlight" );
+ var_Destroy( p_input, "x-start" );
+ var_Destroy( p_input, "x-end" );
+ var_Destroy( p_input, "y-start" );
+ var_Destroy( p_input, "y-end" );
+ var_Destroy( p_input, "color" );
+ var_Destroy( p_input, "menu-palette" );
+
+ vlc_object_release( p_input );
+
+ msg_Dbg( &demuxer, "Stopping the UI Hook" );
+ }
+ b_ui_hooked = false;
+}
+
+int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ event_thread_t *p_ev = (event_thread_t *) p_data;
+ vlc_mutex_lock( &p_ev->lock );
+ if( psz_var[6] == 'c' )
+ {
+ p_ev->b_clicked = VLC_TRUE;
+ msg_Dbg( p_this, "Event Mouse: clicked");
+ }
+ else if( psz_var[6] == 'm' )
+ p_ev->b_moved = VLC_TRUE;
+ vlc_mutex_unlock( &p_ev->lock );
+
+ return VLC_SUCCESS;
+}
+
+int demux_sys_t::EventKey( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ event_thread_t *p_ev = (event_thread_t *) p_data;
+ vlc_mutex_lock( &p_ev->lock );
+ p_ev->b_key = VLC_TRUE;
+ vlc_mutex_unlock( &p_ev->lock );
+ msg_Dbg( p_this, "Event Key");
+
+ return VLC_SUCCESS;
+}
+
+int demux_sys_t::EventThread( vlc_object_t *p_this )
+{
+ event_thread_t *p_ev = (event_thread_t*)p_this;
+ demux_sys_t *p_sys = p_ev->p_demux->p_sys;
+ vlc_object_t *p_vout = NULL;
+
+ p_ev->b_moved = VLC_FALSE;
+ p_ev->b_clicked = VLC_FALSE;
+ p_ev->b_key = VLC_FALSE;
+
+ /* catch all key event */
+ var_AddCallback( p_ev->p_libvlc, "key-pressed", EventKey, p_ev );
+
+ /* main loop */
+ while( !p_ev->b_die )
+ {
+ if ( !p_sys->b_pci_packet_set )
+ {
+ /* Wait 100ms */
+ msleep( 100000 );
+ continue;
+ }
+
+ vlc_bool_t b_activated = VLC_FALSE;
+
+ /* KEY part */
+ if( p_ev->b_key )
+ {
+ vlc_value_t valk;
+ struct libvlc_int_t::hotkey *p_hotkeys = p_ev->p_libvlc->p_hotkeys;
+ int i, i_action = -1;
+
+ msg_Dbg( p_ev->p_demux, "Handle Key Event");
+
+ vlc_mutex_lock( &p_ev->lock );
+
+ pci_t *pci = (pci_t *) &p_sys->pci_packet;
+
+ var_Get( p_ev->p_libvlc, "key-pressed", &valk );
+ for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
+ {
+ if( p_hotkeys[i].i_key == valk.i_int )
+ {
+ i_action = p_hotkeys[i].i_action;
+ }
+ }
+
+ uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
+
+ switch( i_action )
+ {
+ case ACTIONID_NAV_LEFT:
+ if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
+ {
+ btni_t *p_button_ptr = &(pci->hli.btnit[i_curr_button-1]);
+ if ( p_button_ptr->left > 0 && p_button_ptr->left <= pci->hli.hl_gi.btn_ns )
+ {
+ i_curr_button = p_button_ptr->left;
+ p_sys->dvd_interpretor.SetSPRM( 0x88, i_curr_button );
+ btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
+ if ( button_ptr.auto_action_mode )
+ {
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ }
+ }
+ break;
+ case ACTIONID_NAV_RIGHT:
+ if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
+ {
+ btni_t *p_button_ptr = &(pci->hli.btnit[i_curr_button-1]);
+ if ( p_button_ptr->right > 0 && p_button_ptr->right <= pci->hli.hl_gi.btn_ns )
+ {
+ i_curr_button = p_button_ptr->right;
+ p_sys->dvd_interpretor.SetSPRM( 0x88, i_curr_button );
+ btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
+ if ( button_ptr.auto_action_mode )
+ {
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ }
+ }
+ break;
+ case ACTIONID_NAV_UP:
+ if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
+ {
+ btni_t *p_button_ptr = &(pci->hli.btnit[i_curr_button-1]);
+ if ( p_button_ptr->up > 0 && p_button_ptr->up <= pci->hli.hl_gi.btn_ns )
+ {
+ i_curr_button = p_button_ptr->up;
+ p_sys->dvd_interpretor.SetSPRM( 0x88, i_curr_button );
+ btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
+ if ( button_ptr.auto_action_mode )
+ {
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ }
+ }
+ break;
+ case ACTIONID_NAV_DOWN:
+ if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
+ {
+ btni_t *p_button_ptr = &(pci->hli.btnit[i_curr_button-1]);
+ if ( p_button_ptr->down > 0 && p_button_ptr->down <= pci->hli.hl_gi.btn_ns )
+ {
+ i_curr_button = p_button_ptr->down;
+ p_sys->dvd_interpretor.SetSPRM( 0x88, i_curr_button );
+ btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
+ if ( button_ptr.auto_action_mode )
+ {
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ }
+ }
+ break;
+ case ACTIONID_NAV_ACTIVATE:
+ b_activated = VLC_TRUE;
+
+ if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
+ {
+ btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
+
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ break;
+ default:
+ break;
+ }
+ p_ev->b_key = VLC_FALSE;
+ vlc_mutex_unlock( &p_ev->lock );
+ }
+
+ /* MOUSE part */
+ if( p_vout && ( p_ev->b_moved || p_ev->b_clicked ) )
+ {
+ vlc_value_t valx, valy;
+
+ vlc_mutex_lock( &p_ev->lock );
+ pci_t *pci = (pci_t *) &p_sys->pci_packet;
+ var_Get( p_vout, "mouse-x", &valx );
+ var_Get( p_vout, "mouse-y", &valy );
+
+ if( p_ev->b_clicked )
+ {
+ int32_t button;
+ int32_t best,dist,d;
+ int32_t mx,my,dx,dy;
+
+ msg_Dbg( p_ev->p_demux, "Handle Mouse Event: Mouse clicked x(%d)*y(%d)", (unsigned)valx.i_int, (unsigned)valy.i_int);
+
+ b_activated = VLC_TRUE;
+ // get current button
+ best = 0;
+ dist = 0x08000000; /* >> than (720*720)+(567*567); */
+ for(button = 1; button <= pci->hli.hl_gi.btn_ns; button++)
+ {
+ btni_t *button_ptr = &(pci->hli.btnit[button-1]);
+
+ if(((unsigned)valx.i_int >= button_ptr->x_start)
+ && ((unsigned)valx.i_int <= button_ptr->x_end)
+ && ((unsigned)valy.i_int >= button_ptr->y_start)
+ && ((unsigned)valy.i_int <= button_ptr->y_end))
+ {
+ mx = (button_ptr->x_start + button_ptr->x_end)/2;
+ my = (button_ptr->y_start + button_ptr->y_end)/2;
+ dx = mx - valx.i_int;
+ dy = my - valy.i_int;
+ d = (dx*dx) + (dy*dy);
+ /* If the mouse is within the button and the mouse is closer
+ * to the center of this button then it is the best choice. */
+ if(d < dist) {
+ dist = d;
+ best = button;
+ }
+ }
+ }
+
+ if ( best != 0)
+ {
+ btni_t button_ptr = pci->hli.btnit[best-1];
+ uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
+
+ msg_Dbg( &p_sys->demuxer, "Clicked button %d", best );
+ vlc_mutex_unlock( &p_ev->lock );
+ vlc_mutex_lock( &p_sys->lock_demuxer );
+
+ // process the button action
+ p_sys->dvd_interpretor.SetSPRM( 0x88, best );
+ p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
+
+ msg_Dbg( &p_sys->demuxer, "Processed button %d", best );
+
+ // select new button
+ if ( best != i_curr_button )
+ {
+ vlc_value_t val;
+
+ if( var_Get( p_sys->p_input, "highlight-mutex", &val ) == VLC_SUCCESS )
+ {
+ vlc_mutex_t *p_mutex = (vlc_mutex_t *) val.p_address;
+ uint32_t i_palette;
+
+ if(button_ptr.btn_coln != 0) {
+ i_palette = pci->hli.btn_colit.btn_coli[button_ptr.btn_coln-1][1];
+ } else {
+ i_palette = 0;
+ }
+
+ for( int i = 0; i < 4; i++ )
+ {
+ uint32_t i_yuv = 0xFF;//p_sys->clut[(hl.palette>>(16+i*4))&0x0f];
+ uint8_t i_alpha = (i_palette>>(i*4))&0x0f;
+ i_alpha = i_alpha == 0xf ? 0xff : i_alpha << 4;
+
+ p_sys->palette[i][0] = (i_yuv >> 16) & 0xff;
+ p_sys->palette[i][1] = (i_yuv >> 0) & 0xff;
+ p_sys->palette[i][2] = (i_yuv >> 8) & 0xff;
+ p_sys->palette[i][3] = i_alpha;
+ }
+
+ vlc_mutex_lock( p_mutex );
+ val.i_int = button_ptr.x_start; var_Set( p_sys->p_input, "x-start", val );
+ val.i_int = button_ptr.x_end; var_Set( p_sys->p_input, "x-end", val );
+ val.i_int = button_ptr.y_start; var_Set( p_sys->p_input, "y-start", val );
+ val.i_int = button_ptr.y_end; var_Set( p_sys->p_input, "y-end", val );
+
+ val.p_address = (void *)p_sys->palette;
+ var_Set( p_sys->p_input, "menu-palette", val );
+
+ val.b_bool = VLC_TRUE; var_Set( p_sys->p_input, "highlight", val );
+ vlc_mutex_unlock( p_mutex );
+ }
+ }
+ vlc_mutex_unlock( &p_sys->lock_demuxer );
+ vlc_mutex_lock( &p_ev->lock );
+ }
+ }
+ else if( p_ev->b_moved )
+ {
+// dvdnav_mouse_select( NULL, pci, valx.i_int, valy.i_int );
+ }
+
+ p_ev->b_moved = VLC_FALSE;
+ p_ev->b_clicked = VLC_FALSE;
+ vlc_mutex_unlock( &p_ev->lock );
+ }
+
+ /* VOUT part */
+ if( p_vout && p_vout->b_die )
+ {
+ var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );
+ var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
+ vlc_object_release( p_vout );
+ p_vout = NULL;
+ }
+
+ else if( p_vout == NULL )
+ {
+ p_vout = (vlc_object_t*) vlc_object_find( p_sys->p_input, VLC_OBJECT_VOUT,
+ FIND_CHILD );
+ if( p_vout)
+ {
+ var_AddCallback( p_vout, "mouse-moved", EventMouse, p_ev );
+ var_AddCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
+ }
+ }
+
+ /* Wait a bit, 10ms */
+ msleep( 10000 );
+ }
+
+ /* Release callback */
+ if( p_vout )
+ {
+ var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );
+ var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
+ vlc_object_release( p_vout );
+ }
+ var_DelCallback( p_ev->p_libvlc, "key-pressed", EventKey, p_ev );
+
+ vlc_mutex_destroy( &p_ev->lock );
+
+ return VLC_SUCCESS;
+}
+