1 /*****************************************************************************
\r
2 * intf_win32.cpp: Win32 interface plugin for vlc
\r
3 *****************************************************************************
\r
4 * Copyright (C) 2002 VideoLAN
\r
6 * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program; if not, write to the Free Software
\r
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
\r
21 *****************************************************************************/
\r
23 /*****************************************************************************
\r
25 *****************************************************************************/
\r
27 #include <stdlib.h> /* malloc(), free() */
\r
28 #include <errno.h> /* ENOMEM */
\r
29 #include <string.h> /* strerror() */
\r
31 #include <vlc/vlc.h>
\r
32 #include <vlc/intf.h>
\r
34 #include "mainframe.h"
\r
36 #include "win32_common.h"
\r
38 intf_thread_t *p_intfGlobal;
\r
40 /*****************************************************************************
\r
42 *****************************************************************************/
\r
43 static int intf_Open ( intf_thread_t *p_intf );
\r
44 static void intf_Close ( intf_thread_t *p_intf );
\r
45 static void intf_Run ( intf_thread_t *p_intf );
\r
47 int Win32Manage( void *p_data );
\r
49 /*****************************************************************************
\r
50 * Functions exported as capabilities. They are declared as static so that
\r
51 * we don't pollute the namespace too much.
\r
52 *****************************************************************************/
\r
53 void _M( intf_getfunctions )( function_list_t * p_function_list )
\r
55 p_function_list->functions.intf.pf_open = intf_Open;
\r
56 p_function_list->functions.intf.pf_close = intf_Close;
\r
57 p_function_list->functions.intf.pf_run = intf_Run;
\r
60 /*****************************************************************************
\r
61 * intf_Open: initialize interface
\r
62 *****************************************************************************/
\r
63 static int intf_Open( intf_thread_t *p_intf )
\r
65 /* Allocate instance and initialize some members */
\r
66 p_intf->p_sys = (intf_sys_s *) malloc( sizeof( intf_sys_t ) );
\r
67 if( p_intf->p_sys == NULL )
\r
69 msg_Err( p_intf, "out of memory" );
\r
73 p_intfGlobal = p_intf;
\r
75 p_intf->p_sys->p_sub = msg_Subscribe( p_intf->p_this );
\r
77 /* Initialize Win32 thread */
\r
78 p_intf->p_sys->b_playing = 0;
\r
79 p_intf->p_sys->b_popup_changed = 0;
\r
80 p_intf->p_sys->i_playing = -1;
\r
81 p_intf->p_sys->b_slider_free = 1;
\r
86 /*****************************************************************************
\r
87 * intf_Close: destroy interface
\r
88 *****************************************************************************/
\r
89 static void intf_Close( intf_thread_t *p_intf )
\r
91 msg_Unsubscribe( p_intf->p_this, p_intf->p_sys->p_sub );
\r
93 /* Destroy structure */
\r
94 free( p_intf->p_sys );
\r
97 /*****************************************************************************
\r
98 * intf_Run: main loop
\r
99 *****************************************************************************/
\r
100 static void intf_Run( intf_thread_t *p_intf )
\r
102 p_intf->p_sys->p_window = new TMainFrameDlg( NULL );
\r
103 p_intf->p_sys->p_playlist = new TPlaylistDlg( NULL );
\r
104 p_intf->p_sys->p_messages = new TMessagesDlg( NULL );
\r
106 /* show main window and wait until it is closed */
\r
107 p_intf->p_sys->p_window->ShowModal();
\r
109 if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;
\r
110 if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;
\r
111 if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;
\r
112 delete p_intf->p_sys->p_messages;
\r
113 delete p_intf->p_sys->p_playlist;
\r
116 /*****************************************************************************
\r
117 * Win32Manage: manage main thread messages
\r
118 *****************************************************************************
\r
119 * In this function, called approx. 10 times a second, we check what the
\r
120 * main program wanted to tell us.
\r
121 *****************************************************************************/
\r
122 int Win32Manage( intf_thread_t *p_intf )
\r
124 vlc_mutex_lock( &p_intf->change_lock );
\r
126 /* If the "display popup" flag has changed */
\r
127 if( p_intf->b_menu_change )
\r
129 /* FIXME: It would be nice to close the popup when the user left-clicks
\r
130 elsewhere, or to actualize the position when he right-clicks again,
\r
131 but i couldn't find a way to close it :-( */
\r
132 TPoint MousePos = Mouse->CursorPos;
\r
133 p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );
\r
134 p_intf->b_menu_change = 0;
\r
137 /* Update the log window */
\r
138 p_intf->p_sys->p_messages->UpdateLog();
\r
140 /* Update the playlist */
\r
141 p_intf->p_sys->p_playlist->Manage( p_intf );
\r
143 if( p_intf->p_vlc->p_input_bank->pp_input[0] != NULL )
\r
145 vlc_mutex_lock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );
\r
147 if( !p_intf->p_vlc->p_input_bank->pp_input[0]->b_die )
\r
149 /* New input or stream map change */
\r
150 if( p_intf->p_vlc->p_input_bank->pp_input[0]->stream.b_changed )
\r
152 p_intf->p_sys->p_window->ModeManage();
\r
153 SetupMenus( p_intf );
\r
154 p_intf->p_sys->b_playing = 1;
\r
157 /* Manage the slider */
\r
158 if( p_intf->p_vlc->p_input_bank->pp_input[0]->stream.b_seekable &&
\r
159 p_intf->p_sys->b_playing )
\r
161 TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;
\r
162 off_t NewValue = TrackBar->Position;
\r
164 #define p_area p_intf->p_vlc->p_input_bank->pp_input[0]->stream.p_selected_area
\r
165 /* If the user hasn't touched the slider since the last time,
\r
166 * then the input can safely change it */
\r
167 if( NewValue == p_intf->p_sys->OldValue )
\r
169 /* Update the value */
\r
170 TrackBar->Position = p_intf->p_sys->OldValue =
\r
171 ( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /
\r
174 /* Otherwise, send message to the input if the user has
\r
175 * finished dragging the slider */
\r
176 else if( p_intf->p_sys->b_slider_free )
\r
178 off_t i_seek = ( NewValue * p_area->i_size ) /
\r
179 (off_t)SLIDER_MAX_VALUE;
\r
181 /* release the lock to be able to seek */
\r
182 vlc_mutex_unlock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );
\r
183 input_Seek( p_intf->p_vlc->p_input_bank->pp_input[0]->p_this, i_seek, INPUT_SEEK_SET );
\r
184 vlc_mutex_lock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );
\r
186 /* Update the old value */
\r
187 p_intf->p_sys->OldValue = NewValue;
\r
190 /* Update the display */
\r
191 // TrackBar->Invalidate();
\r
196 if( p_intf->p_sys->i_part !=
\r
197 p_intf->p_vlc->p_input_bank->pp_input[0]->stream.p_selected_area->i_part )
\r
199 // p_intf->p_sys->b_chapter_update = 1;
\r
200 SetupMenus( p_intf );
\r
204 vlc_mutex_unlock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );
\r
206 else if( p_intf->p_sys->b_playing && !p_intf->p_vlc->b_die )
\r
208 p_intf->p_sys->p_window->ModeManage();
\r
209 p_intf->p_sys->b_playing = 0;
\r
212 /* Manage core vlc functions through the callback */
\r
213 p_intf->pf_manage( p_intf );
\r
215 if( p_intf->p_vlc->b_die )
\r
217 vlc_mutex_unlock( &p_intf->change_lock );
\r
219 /* Prepare to die, young Skywalker */
\r
220 p_intf->p_sys->p_window->ModalResult = mrOk;
\r
226 vlc_mutex_unlock( &p_intf->change_lock );
\r