]> git.sesse.net Git - vlc/blob - plugins/win32/intf_win32.cpp
5efa16852a4fdd29d29bf5f9332191815dcae2cb
[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 \r
110     /* show main window and wait until it is closed */\r
111     p_intf->p_sys->p_window->ShowModal();\r
112 \r
113     if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;\r
114     if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;\r
115     if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;\r
116     delete p_intf->p_sys->p_messages;\r
117     delete p_intf->p_sys->p_playlist;\r
118 }\r
119 \r
120 /*****************************************************************************\r
121  * Win32Manage: manage main thread messages\r
122  *****************************************************************************\r
123  * In this function, called approx. 10 times a second, we check what the\r
124  * main program wanted to tell us.\r
125  *****************************************************************************/\r
126 int Win32Manage( intf_thread_t *p_intf )\r
127 {\r
128     vlc_mutex_lock( &p_intf->change_lock );\r
129 \r
130     /* If the "display popup" flag has changed */\r
131     if( p_intf->b_menu_change )\r
132     {\r
133         /* FIXME: It would be nice to close the popup when the user left-clicks\r
134         elsewhere, or to actualize the position when he right-clicks again,\r
135         but i couldn't find a way to close it :-( */\r
136         TPoint MousePos = Mouse->CursorPos;\r
137         p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );\r
138         p_intf->b_menu_change = 0;\r
139     }\r
140 \r
141     /* Update the log window */\r
142     p_intf->p_sys->p_messages->UpdateLog();\r
143 \r
144     /* Update the playlist */\r
145     p_intf->p_sys->p_playlist->Manage( p_intf );\r
146 \r
147     if( p_input_bank->pp_input[0] != NULL )\r
148     {\r
149         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
150 \r
151         if( !p_input_bank->pp_input[0]->b_die )\r
152         {\r
153             /* New input or stream map change */\r
154             if( p_input_bank->pp_input[0]->stream.b_changed )\r
155             {\r
156                 p_intf->p_sys->p_window->ModeManage();\r
157                 SetupMenus( p_intf );\r
158                 p_intf->p_sys->b_playing = 1;\r
159             }\r
160 \r
161             /* Manage the slider */\r
162             if( p_input_bank->pp_input[0]->stream.b_seekable &&\r
163                 p_intf->p_sys->b_playing )\r
164             {\r
165                 TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;\r
166                 off_t NewValue = TrackBar->Position;\r
167 \r
168 #define p_area p_input_bank->pp_input[0]->stream.p_selected_area\r
169                 /* If the user hasn't touched the slider since the last time,\r
170                  * then the input can safely change it */\r
171                 if( NewValue == p_intf->p_sys->OldValue )\r
172                 {\r
173                     /* Update the value */\r
174                     TrackBar->Position = p_intf->p_sys->OldValue =\r
175                         ( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /\r
176                                 p_area->i_size;\r
177                 }\r
178                 /* Otherwise, send message to the input if the user has\r
179                  * finished dragging the slider */\r
180                 else if( p_intf->p_sys->b_slider_free )\r
181                 {\r
182                     off_t i_seek = ( NewValue * p_area->i_size ) /\r
183                                 (off_t)SLIDER_MAX_VALUE;\r
184 \r
185                     /* release the lock to be able to seek */\r
186                     vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
187                     input_Seek( p_input_bank->pp_input[0], i_seek );\r
188                     vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
189 \r
190                     /* Update the old value */\r
191                     p_intf->p_sys->OldValue = NewValue;\r
192                 }\r
193 \r
194                 /* Update the display */\r
195 //                TrackBar->Invalidate();\r
196                 \r
197 #    undef p_area\r
198             }\r
199 \r
200             if( p_intf->p_sys->i_part !=\r
201                 p_input_bank->pp_input[0]->stream.p_selected_area->i_part )\r
202             {\r
203 //                p_intf->p_sys->b_chapter_update = 1;\r
204                 SetupMenus( p_intf );\r
205             }\r
206         }\r
207 \r
208         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );\r
209     }\r
210     else if( p_intf->p_sys->b_playing && !p_intf->b_die )\r
211     {\r
212         p_intf->p_sys->p_window->ModeManage();\r
213         p_intf->p_sys->b_playing = 0;\r
214     }\r
215 \r
216     /* Manage core vlc functions through the callback */\r
217     p_intf->pf_manage( p_intf );\r
218 \r
219     if( p_intf->b_die )\r
220     {\r
221         vlc_mutex_unlock( &p_intf->change_lock );\r
222 \r
223         /* Prepare to die, young Skywalker */\r
224         p_intf->p_sys->p_window->ModalResult = mrOk;\r
225 \r
226         /* Just in case */\r
227         return( FALSE );\r
228     }\r
229      \r
230     vlc_mutex_unlock( &p_intf->change_lock );\r
231 \r
232     return( TRUE );\r
233 }\r
234 \r