]> git.sesse.net Git - vlc/blob - plugins/win32/intf_win32.cpp
7f3aa7b95bb1e1f75f30f39d7bf42e2a6860dfb9
[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 <vlc/vlc.h>\r
32 #include <vlc/intf.h>\r
33 \r
34 #include "mainframe.h"\r
35 #include "menu.h"\r
36 #include "win32_common.h"\r
37 \r
38 intf_thread_t *p_intfGlobal;\r
39 \r
40 /*****************************************************************************\r
41  * Local prototypes.\r
42  *****************************************************************************/\r
43 static void intf_Run       ( intf_thread_t *p_intf );\r
44 \r
45 int Win32Manage( void *p_data );\r
46 \r
47 /*****************************************************************************\r
48  * Open: initialize interface\r
49  *****************************************************************************/\r
50 int E_(Open)( vlc_object_t *p_this )\r
51 {\r
52     intf_thread_t *p_intf = (intf_thread_t *)p_this;\r
53 \r
54     /* Allocate instance and initialize some members */\r
55     p_intf->p_sys = (intf_sys_s *) malloc( sizeof( intf_sys_t ) );\r
56     if( p_intf->p_sys == NULL )\r
57     {\r
58         msg_Err( p_intf, "out of memory" );\r
59         return( 1 );\r
60     };\r
61 \r
62     p_intfGlobal = p_intf;\r
63     p_intf->pf_run = intf_Run;\r
64 \r
65     p_intf->p_sys->p_sub = msg_Subscribe( p_intf );\r
66 \r
67     /* Initialize Win32 thread */\r
68     p_intf->p_sys->b_playing = 0;\r
69     p_intf->p_sys->b_popup_changed = 0;\r
70 \r
71     p_intf->p_sys->p_input = NULL;\r
72     p_intf->p_sys->i_playing = -1;\r
73     p_intf->p_sys->b_slider_free = 1;\r
74 \r
75     return( 0 );\r
76 }\r
77 \r
78 /*****************************************************************************\r
79  * Close: destroy interface\r
80  *****************************************************************************/\r
81 void E_(Close)( vlc_object_t *p_this )\r
82 {\r
83     intf_thread_t *p_intf = (intf_thread_t *)p_this;\r
84 \r
85     if( p_intf->p_sys->p_input )\r
86     {\r
87         vlc_object_release( p_intf->p_sys->p_input );\r
88     }\r
89 \r
90     msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );\r
91 \r
92     /* Destroy structure */\r
93     free( p_intf->p_sys );\r
94 }\r
95 \r
96 /*****************************************************************************\r
97  * intf_Run: main loop\r
98  *****************************************************************************/\r
99 static void intf_Run( intf_thread_t *p_intf )\r
100 {\r
101     p_intf->p_sys->p_window = new TMainFrameDlg( NULL );\r
102     p_intf->p_sys->p_playwin = new TPlaylistDlg( NULL );\r
103     p_intf->p_sys->p_messages = new TMessagesDlg( NULL );\r
104 \r
105     /* show main window and wait until it is closed */\r
106     p_intf->p_sys->p_window->ShowModal();\r
107 \r
108     if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;\r
109     if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;\r
110     if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;\r
111     delete p_intf->p_sys->p_messages;\r
112     delete p_intf->p_sys->p_playwin;\r
113 }\r
114 \r
115 /*****************************************************************************\r
116  * Win32Manage: manage main thread messages\r
117  *****************************************************************************\r
118  * In this function, called approx. 10 times a second, we check what the\r
119  * main program wanted to tell us.\r
120  *****************************************************************************/\r
121 int Win32Manage( intf_thread_t *p_intf )\r
122 {\r
123     vlc_mutex_lock( &p_intf->change_lock );\r
124 \r
125     /* If the "display popup" flag has changed */\r
126     if( p_intf->b_menu_change )\r
127     {\r
128         /* FIXME: It would be nice to close the popup when the user left-clicks\r
129         elsewhere, or to actualize the position when he right-clicks again,\r
130         but i couldn't find a way to close it :-( */\r
131         TPoint MousePos = Mouse->CursorPos;\r
132         p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );\r
133         p_intf->b_menu_change = 0;\r
134     }\r
135 \r
136     /* Update the log window */\r
137     p_intf->p_sys->p_messages->UpdateLog();\r
138 \r
139     /* Update the playlist */\r
140     p_intf->p_sys->p_playwin->Manage( p_intf );\r
141 \r
142     /* Update the input */\r
143     if( p_intf->p_sys->p_input == NULL )\r
144     {\r
145         p_intf->p_sys->p_input = (input_thread_t *)\r
146                     vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );\r
147     }\r
148     else if( p_intf->p_sys->p_input->b_dead )\r
149     {\r
150         vlc_object_release( p_intf->p_sys->p_input );\r
151         p_intf->p_sys->p_input = NULL;\r
152     }\r
153     \r
154     if( p_intf->p_sys->p_input )\r
155     {\r
156         input_thread_t *p_input = p_intf->p_sys->p_input;\r
157 \r
158         vlc_mutex_lock( &p_input->stream.stream_lock );\r
159 \r
160         if( !p_input->b_die )\r
161         {\r
162             /* New input or stream map change */\r
163             if( p_input->stream.b_changed )\r
164             {\r
165                 p_intf->p_sys->p_window->ModeManage();\r
166                 SetupMenus( p_intf );\r
167                 p_intf->p_sys->b_playing = 1;\r
168             }\r
169 \r
170             /* Manage the slider */\r
171             if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )\r
172             {\r
173                 TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;\r
174                 off_t NewValue = TrackBar->Position;\r
175 \r
176 #define p_area p_input->stream.p_selected_area\r
177                 /* If the user hasn't touched the slider since the last time,\r
178                  * then the input can safely change it */\r
179                 if( NewValue == p_intf->p_sys->OldValue )\r
180                 {\r
181                     /* Update the value */\r
182                     TrackBar->Position = p_intf->p_sys->OldValue =\r
183                         ( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /\r
184                                 p_area->i_size;\r
185                 }\r
186                 /* Otherwise, send message to the input if the user has\r
187                  * finished dragging the slider */\r
188                 else if( p_intf->p_sys->b_slider_free )\r
189                 {\r
190                     off_t i_seek = ( NewValue * p_area->i_size ) /\r
191                                 (off_t)SLIDER_MAX_VALUE;\r
192 \r
193                     /* release the lock to be able to seek */\r
194                     vlc_mutex_unlock( &p_input->stream.stream_lock );\r
195                     input_Seek( p_input, i_seek, INPUT_SEEK_SET );\r
196                     vlc_mutex_lock( &p_input->stream.stream_lock );\r
197 \r
198                     /* Update the old value */\r
199                     p_intf->p_sys->OldValue = NewValue;\r
200                 }\r
201 \r
202                 /* Update the display */\r
203 //                TrackBar->Invalidate();\r
204                 \r
205 #    undef p_area\r
206             }\r
207 \r
208             if( p_intf->p_sys->i_part !=\r
209                 p_input->stream.p_selected_area->i_part )\r
210             {\r
211 //                p_intf->p_sys->b_chapter_update = 1;\r
212                 SetupMenus( p_intf );\r
213             }\r
214         }\r
215 \r
216         vlc_mutex_unlock( &p_input->stream.stream_lock );\r
217     }\r
218     else if( p_intf->p_sys->b_playing && !p_intf->b_die )\r
219     {\r
220         p_intf->p_sys->p_window->ModeManage();\r
221         p_intf->p_sys->b_playing = 0;\r
222     }\r
223 \r
224     if( p_intf->b_die )\r
225     {\r
226         vlc_mutex_unlock( &p_intf->change_lock );\r
227 \r
228         /* Prepare to die, young Skywalker */\r
229         p_intf->p_sys->p_window->ModalResult = mrOk;\r
230 \r
231         /* Just in case */\r
232         return( FALSE );\r
233     }\r
234      \r
235     vlc_mutex_unlock( &p_intf->change_lock );\r
236 \r
237     return( TRUE );\r
238 }\r
239 \r