]> git.sesse.net Git - vlc/blob - plugins/win32/intf_win32.cpp
* ALL: the first libvlc commit.
[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 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
46 \r
47 int Win32Manage( void *p_data );\r
48 \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
54 {\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
58 }\r
59 \r
60 /*****************************************************************************\r
61  * intf_Open: initialize interface\r
62  *****************************************************************************/\r
63 static int intf_Open( intf_thread_t *p_intf )\r
64 {\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
68     {\r
69         msg_Err( p_intf, "out of memory" );\r
70         return( 1 );\r
71     };\r
72 \r
73     p_intfGlobal = p_intf;\r
74 \r
75     p_intf->p_sys->p_sub = msg_Subscribe( p_intf->p_this );\r
76 \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
82 \r
83     return( 0 );\r
84 }\r
85 \r
86 /*****************************************************************************\r
87  * intf_Close: destroy interface\r
88  *****************************************************************************/\r
89 static void intf_Close( intf_thread_t *p_intf )\r
90 {\r
91     msg_Unsubscribe( p_intf->p_this, p_intf->p_sys->p_sub );\r
92 \r
93     /* Destroy structure */\r
94     free( p_intf->p_sys );\r
95 }\r
96 \r
97 /*****************************************************************************\r
98  * intf_Run: main loop\r
99  *****************************************************************************/\r
100 static void intf_Run( intf_thread_t *p_intf )\r
101 {\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
105 \r
106     /* show main window and wait until it is closed */\r
107     p_intf->p_sys->p_window->ShowModal();\r
108 \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
114 }\r
115 \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
123 {\r
124     vlc_mutex_lock( &p_intf->change_lock );\r
125 \r
126     /* If the "display popup" flag has changed */\r
127     if( p_intf->b_menu_change )\r
128     {\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
135     }\r
136 \r
137     /* Update the log window */\r
138     p_intf->p_sys->p_messages->UpdateLog();\r
139 \r
140     /* Update the playlist */\r
141     p_intf->p_sys->p_playlist->Manage( p_intf );\r
142 \r
143     if( p_intf->p_vlc->p_input_bank->pp_input[0] != NULL )\r
144     {\r
145         vlc_mutex_lock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );\r
146 \r
147         if( !p_intf->p_vlc->p_input_bank->pp_input[0]->b_die )\r
148         {\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
151             {\r
152                 p_intf->p_sys->p_window->ModeManage();\r
153                 SetupMenus( p_intf );\r
154                 p_intf->p_sys->b_playing = 1;\r
155             }\r
156 \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
160             {\r
161                 TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;\r
162                 off_t NewValue = TrackBar->Position;\r
163 \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
168                 {\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
172                                 p_area->i_size;\r
173                 }\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
177                 {\r
178                     off_t i_seek = ( NewValue * p_area->i_size ) /\r
179                                 (off_t)SLIDER_MAX_VALUE;\r
180 \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
185 \r
186                     /* Update the old value */\r
187                     p_intf->p_sys->OldValue = NewValue;\r
188                 }\r
189 \r
190                 /* Update the display */\r
191 //                TrackBar->Invalidate();\r
192                 \r
193 #    undef p_area\r
194             }\r
195 \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
198             {\r
199 //                p_intf->p_sys->b_chapter_update = 1;\r
200                 SetupMenus( p_intf );\r
201             }\r
202         }\r
203 \r
204         vlc_mutex_unlock( &p_intf->p_vlc->p_input_bank->pp_input[0]->stream.stream_lock );\r
205     }\r
206     else if( p_intf->p_sys->b_playing && !p_intf->p_vlc->b_die )\r
207     {\r
208         p_intf->p_sys->p_window->ModeManage();\r
209         p_intf->p_sys->b_playing = 0;\r
210     }\r
211 \r
212     /* Manage core vlc functions through the callback */\r
213     p_intf->pf_manage( p_intf );\r
214 \r
215     if( p_intf->p_vlc->b_die )\r
216     {\r
217         vlc_mutex_unlock( &p_intf->change_lock );\r
218 \r
219         /* Prepare to die, young Skywalker */\r
220         p_intf->p_sys->p_window->ModalResult = mrOk;\r
221 \r
222         /* Just in case */\r
223         return( FALSE );\r
224     }\r
225      \r
226     vlc_mutex_unlock( &p_intf->change_lock );\r
227 \r
228     return( TRUE );\r
229 }\r
230 \r