]> git.sesse.net Git - vlc/blob - plugins/win32/intf_win32.cpp
* Added a win32 interface plugin, developed with Borland C++ Builder.
[vlc] / plugins / win32 / intf_win32.cpp
1 /*****************************************************************************\r
2  * intf_win32.cpp: Win32 interface plugin for vlc\r
3  *****************************************************************************\r
4  * Copyright (C) 2002 VideoLAN\r
5  *\r
6  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>\r
7  *\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
12  *\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
17  *\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
22 \r
23 /*****************************************************************************\r
24  * Preamble\r
25  *****************************************************************************/\r
26 #include <vcl.h>\r
27 #include <stdlib.h>                                      /* malloc(), free() */\r
28 #include <errno.h>                                                /* ENOMEM */\r
29 #include <string.h>                                           /* strerror() */\r
30 \r
31 #include <videolan/vlc.h>\r
32 \r
33 #include "stream_control.h"\r
34 #include "input_ext-intf.h"\r
35 \r
36 #include "interface.h"\r
37 \r
38 #include "mainframe.h"\r
39 #include "menu.h"\r
40 #include "win32_common.h"\r
41 \r
42 struct intf_thread_s *p_intfGlobal;\r
43 \r
44 /*****************************************************************************\r
45  * Local prototypes.\r
46  *****************************************************************************/\r
47 static int  intf_Open      ( intf_thread_t *p_intf );\r
48 static void intf_Close     ( intf_thread_t *p_intf );\r
49 static void intf_Run       ( intf_thread_t *p_intf );\r
50 \r
51 int Win32Manage( void *p_data );\r
52 \r
53 /*****************************************************************************\r
54  * Functions exported as capabilities. They are declared as static so that\r
55  * we don't pollute the namespace too much.\r
56  *****************************************************************************/\r
57 void _M( intf_getfunctions )( function_list_t * p_function_list )\r
58 {\r
59     p_function_list->functions.intf.pf_open  = intf_Open;\r
60     p_function_list->functions.intf.pf_close = intf_Close;\r
61     p_function_list->functions.intf.pf_run   = intf_Run;\r
62 }\r
63 \r
64 /*****************************************************************************\r
65  * intf_Open: initialize interface\r
66  *****************************************************************************/\r
67 static int intf_Open( intf_thread_t *p_intf )\r
68 {\r
69     /* Allocate instance and initialize some members */\r
70     p_intf->p_sys = (intf_sys_s *) malloc( sizeof( intf_sys_t ) );\r
71     if( p_intf->p_sys == NULL )\r
72     {\r
73         intf_ErrMsg( "intf error: %s", strerror(ENOMEM) );\r
74         return( 1 );\r
75     };\r
76 \r
77     p_intfGlobal = p_intf;\r
78 \r
79     p_intf->p_sys->p_sub = intf_MsgSub();\r
80 \r
81     /* Initialize Win32 thread */\r
82     p_intf->p_sys->b_playing = 0;\r
83     p_intf->p_sys->b_popup_changed = 0;\r
84     p_intf->p_sys->i_playing = -1;\r
85     p_intf->p_sys->b_slider_free = 1;\r
86 \r
87     return( 0 );\r
88 }\r
89 \r
90 /*****************************************************************************\r
91  * intf_Close: destroy interface\r
92  *****************************************************************************/\r
93 static void intf_Close( intf_thread_t *p_intf )\r
94 {\r
95     intf_MsgUnsub( p_intf->p_sys->p_sub );\r
96 \r
97     /* Destroy structure */\r
98     free( p_intf->p_sys );\r
99 }\r
100 \r
101 /*****************************************************************************\r
102  * intf_Run: main loop\r
103  *****************************************************************************/\r
104 static void intf_Run( intf_thread_t *p_intf )\r
105 {\r
106     p_intf->p_sys->p_window = new TMainFrameDlg( NULL );\r
107     p_intf->p_sys->p_playlist = new TPlaylistDlg( NULL );\r
108     p_intf->p_sys->p_messages = new TMessagesDlg( NULL );\r
109     p_intf->p_sys->p_window->ShowModal();\r
110     if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;\r
111     if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;\r
112     if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;\r
113     delete p_intf->p_sys->p_messages;\r
114     delete p_intf->p_sys->p_playlist;\r
115 }\r
116 \r
117 /*****************************************************************************\r
118  * Win32Manage: manage main thread messages\r
119  *****************************************************************************\r
120  * In this function, called approx. 10 times a second, we check what the\r
121  * main program wanted to tell us.\r
122  *****************************************************************************/\r
123 int Win32Manage( intf_thread_t *p_intf )\r
124 {\r
125     vlc_mutex_lock( &p_intf->change_lock );\r
126 \r
127     /* If the "display popup" flag has changed */\r
128     if( p_intf->b_menu_change )\r
129     {\r
130         /* FIXME: It would be nice to close the popup when the user left-clicks\r
131         elsewhere, or to actualize the position when he right-clicks again,\r
132         but i couldn't find a way to close it :-( */\r
133         TPoint MousePos = Mouse->CursorPos;\r
134         p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );\r
135         p_intf->b_menu_change = 0;\r
136     }\r
137 \r
138     /* Update the log window */\r
139     p_intf->p_sys->p_messages->UpdateLog();\r
140 \r
141     /* Update the playlist */\r
142     p_intf->p_sys->p_playlist->Manage( p_intf );\r
143 \r
144     if( p_input_bank->pp_input[0] != NULL )\r
145     {\r
146         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
147 \r
148         if( !p_input_bank->pp_input[0]->b_die )\r
149         {\r
150             /* New input or stream map change */\r
151             if( p_input_bank->pp_input[0]->stream.b_changed )\r
152             {\r
153                 p_intf->p_sys->p_window->ModeManage();\r
154                 SetupMenus( p_intf );\r
155                 p_intf->p_sys->b_playing = 1;\r
156             }\r
157 \r
158             /* Manage the slider */\r
159             if( p_input_bank->pp_input[0]->stream.b_seekable &&\r
160                 p_intf->p_sys->b_playing )\r
161             {\r
162                 TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;\r
163                 off_t NewValue = TrackBar->Position;\r
164 \r
165 #define p_area p_input_bank->pp_input[0]->stream.p_selected_area\r
166                 /* If the user hasn't touched the slider since the last time,\r
167                  * then the input can safely change it */\r
168                 if( NewValue == p_intf->p_sys->OldValue )\r
169                 {\r
170                     /* Update the value */\r
171                     TrackBar->Position = p_intf->p_sys->OldValue =\r
172                         ( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /\r
173                                 p_area->i_size;\r
174                 }\r
175                 /* Otherwise, send message to the input if the user has\r
176                  * finished dragging the slider */\r
177                 else if( p_intf->p_sys->b_slider_free )\r
178                 {\r
179                     off_t i_seek = ( NewValue * p_area->i_size ) /\r
180                                 (off_t)SLIDER_MAX_VALUE;\r
181 \r
182                     /* release the lock to be able to seek */\r
183                     vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
184                     input_Seek( p_input_bank->pp_input[0], i_seek );\r
185                     vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
186 \r
187                     /* Update the old value */\r
188                     p_intf->p_sys->OldValue = NewValue;\r
189                 }\r
190 \r
191                 /* Update the display */\r
192 //                TrackBar->Invalidate();\r
193                 \r
194 #    undef p_area\r
195             }\r
196 \r
197             if( p_intf->p_sys->i_part !=\r
198                 p_input_bank->pp_input[0]->stream.p_selected_area->i_part )\r
199             {\r
200 //                p_intf->p_sys->b_chapter_update = 1;\r
201                 SetupMenus( p_intf );\r
202             }\r
203         }\r
204 \r
205         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
206     }\r
207     else if( p_intf->p_sys->b_playing && !p_intf->b_die )\r
208     {\r
209         p_intf->p_sys->p_window->ModeManage();\r
210         p_intf->p_sys->b_playing = 0;\r
211     }\r
212 \r
213     /* Manage core vlc functions through the callback */\r
214     p_intf->pf_manage( p_intf );\r
215 \r
216     if( p_intf->b_die )\r
217     {\r
218         vlc_mutex_unlock( &p_intf->change_lock );\r
219 \r
220         /* Prepare to die, young Skywalker */\r
221         p_intf->p_sys->p_window->ModalResult = mrOk;\r
222         delete p_intf->p_sys->p_window;\r
223 \r
224         /* Just in case */\r
225         return( FALSE );\r
226     }\r
227      \r
228     vlc_mutex_unlock( &p_intf->change_lock );\r
229 \r
230     return( TRUE );\r
231 }\r
232 \r