]> git.sesse.net Git - vlc/blob - modules/control/corba/corba.c
dd2b434760474a0087828329b4ee6c3a11a7de3d
[vlc] / modules / control / corba / corba.c
1 /*****************************************************************************
2  * corba.c : CORBA (ORBit) remote control plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id$
6  *
7  * Authors: Olivier Aubert <oaubert@lisi.univ-lyon1.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 /* For CORBA */
28 #include "MediaControl.h"
29 #include "orbit/poa/portableserver-poa-type.h"
30 #include "mediacontrol-core.h"
31
32 #include <vlc/vlc.h>
33 #include <vlc/intf.h>
34 #include <vlc/vout.h>
35 #include <vlc/aout.h>
36
37 #include <errno.h>
38 #include <unistd.h>
39
40 /* FIXME: replace this to ~/.vlc/vlc-ior.ref thanks to
41    config_GetHomeDir( ) */
42 #ifndef __WIN32__
43 #define VLC_IOR_FILE "/tmp/vlc-ior.ref"
44 #else
45 #define VLC_IOR_FILE "vlc-ior-ref"
46 #endif
47
48 #define MC_TRY exception = mediacontrol_exception_init( exception )
49 #define MC_EXCEPT( return_value )  \
50   if ( exception->code )\
51   { \
52       corba_raise( ev, exception ); \
53       mediacontrol_exception_free( exception ); \
54       return return_value; \
55   } else { mediacontrol_exception_free( exception ); }
56
57 #define handle_exception( m ) if( ev->_major != CORBA_NO_EXCEPTION ) \
58     { \
59         msg_Err( servant->p_intf, m ); \
60         return; \
61     }
62
63 #define handle_exception_no_servant( p,m ) if( ev->_major != CORBA_NO_EXCEPTION ) \
64     { \
65         msg_Err( p, m ); \
66         return; \
67     }
68
69 static void corba_raise( CORBA_Environment *ev, mediacontrol_Exception *exception )
70 {
71     char *corba_exception=NULL;
72     char* i_type = NULL;
73  
74     switch( exception->code )
75     {
76     case mediacontrol_InternalException:
77         corba_exception = ( char* )VLC_InternalException__alloc();
78         i_type = ex_VLC_InternalException;
79         break;
80     case mediacontrol_PlaylistException:
81         corba_exception = ( char* )VLC_PlaylistException__alloc();
82         i_type = ex_VLC_PlaylistException;
83         break;
84     case mediacontrol_InvalidPosition:
85         corba_exception = ( char* )VLC_InvalidPosition__alloc();
86         i_type = ex_VLC_InvalidPosition;
87         break;
88     case mediacontrol_PositionKeyNotSupported:
89         corba_exception = ( char* )VLC_PositionKeyNotSupported__alloc();
90         i_type = ex_VLC_PositionKeyNotSupported;
91         break;
92     case mediacontrol_PositionOriginNotSupported:
93         corba_exception = ( char* )VLC_PositionOriginNotSupported__alloc();
94         i_type = ex_VLC_PositionOriginNotSupported;
95         break;
96     }
97     ( (VLC_InternalException* )corba_exception )->message = CORBA_string_dup( exception->message );
98     CORBA_exception_set( ev, CORBA_USER_EXCEPTION, i_type, corba_exception );
99     return;
100 }
101
102 static mediacontrol_Position* corba_position_corba_to_c( const VLC_Position* position )
103 {
104     mediacontrol_Position* retval;
105     
106     retval = ( mediacontrol_Position* )malloc( sizeof( mediacontrol_Position ) );
107     if( ! retval )
108         return NULL;
109     retval->origin = position->origin;
110     retval->key    = position->key;
111     retval->value  = position->value;
112     return retval;
113 }
114
115 static VLC_Position* corba_position_c_to_corba( const mediacontrol_Position* position )
116 {
117     VLC_Position* retval;
118
119     retval = ( VLC_Position* )malloc( sizeof( VLC_Position ) );
120     if( ! retval )
121         return NULL;
122     retval->origin = position->origin;
123     retval->key    = position->key;
124     retval->value  = position->value;
125     return retval;
126 }
127
128 /*****************************************************************************
129  * intf_sys_t: description and status of corba interface
130  *****************************************************************************/
131 struct intf_sys_t
132 {
133     CORBA_ORB                 orb;
134     GMainLoop*                corbaloop;
135     mediacontrol_Instance     *mc;
136     msg_subscription_t* p_sub;  /* message bank subscription */
137 };
138
139 /*** App-specific servant structures ***/
140
141 /* We can add attributes to this structure, which is both a pointer on a
142    specific structure, and on a POA_VLC_MediaControl ( servant ). Cf
143    http://developer.gnome.org/doc/guides/corba/html/corba-poa-example.html */
144
145 typedef struct
146 {
147     POA_VLC_MediaControl servant;
148     PortableServer_POA poa;
149     /* Ajouter ici les attributs utiles */
150     mediacontrol_Instance     *mc;
151     intf_thread_t             *p_intf;
152 } impl_POA_VLC_MediaControl;
153
154 /* Beginning of the CORBA code generated in Mediacontrol-skelimpl.c */
155 /* BEGIN INSERT */
156 /*** Implementation stub prototypes ***/
157
158 static void impl_VLC_MediaControl__destroy( impl_POA_VLC_MediaControl *
159                                             servant, CORBA_Environment * ev );
160
161 static VLC_Position
162 impl_VLC_MediaControl_get_media_position( impl_POA_VLC_MediaControl * servant,
163                                           const VLC_PositionOrigin an_origin,
164                                           const VLC_PositionKey a_key,
165                                           CORBA_Environment * ev );
166
167 static void
168 impl_VLC_MediaControl_set_media_position( impl_POA_VLC_MediaControl * servant,
169                                           const VLC_Position * a_position,
170                                           CORBA_Environment * ev );
171
172 static void
173 impl_VLC_MediaControl_start( impl_POA_VLC_MediaControl * servant,
174                              const VLC_Position * a_position,
175                              CORBA_Environment * ev );
176
177 static void
178 impl_VLC_MediaControl_pause( impl_POA_VLC_MediaControl * servant,
179                              const VLC_Position * a_position,
180                              CORBA_Environment * ev );
181
182 static void
183 impl_VLC_MediaControl_resume( impl_POA_VLC_MediaControl * servant,
184                               const VLC_Position * a_position,
185                               CORBA_Environment * ev );
186
187 static void
188 impl_VLC_MediaControl_stop( impl_POA_VLC_MediaControl * servant,
189                             const VLC_Position * a_position,
190                             CORBA_Environment * ev );
191
192 static void
193 impl_VLC_MediaControl_exit( impl_POA_VLC_MediaControl * servant,
194                             CORBA_Environment * ev );
195
196 static void
197 impl_VLC_MediaControl_playlist_add_item( impl_POA_VLC_MediaControl * servant,
198                                          const CORBA_char * a_file,
199                                          CORBA_Environment * ev );
200
201 static void
202 impl_VLC_MediaControl_playlist_clear( impl_POA_VLC_MediaControl * servant,
203                                       CORBA_Environment * ev );
204
205 static VLC_PlaylistSeq
206 *impl_VLC_MediaControl_playlist_get_list( impl_POA_VLC_MediaControl *
207                                           servant, CORBA_Environment * ev );
208
209 static VLC_RGBPicture
210 *impl_VLC_MediaControl_snapshot( impl_POA_VLC_MediaControl * servant,
211                                  const VLC_Position * a_position,
212                                  CORBA_Environment * ev );
213
214 static VLC_RGBPictureSeq
215 *impl_VLC_MediaControl_all_snapshots( impl_POA_VLC_MediaControl * servant,
216                                       CORBA_Environment * ev );
217
218 static void
219 impl_VLC_MediaControl_display_text( impl_POA_VLC_MediaControl * servant,
220                                     const CORBA_char * message,
221                                     const VLC_Position * begin,
222                                     const VLC_Position * end,
223                                     CORBA_Environment * ev );
224
225 static VLC_StreamInformation
226 *impl_VLC_MediaControl_get_stream_information( impl_POA_VLC_MediaControl *
227                                                servant,
228                                                CORBA_Environment * ev );
229
230 static CORBA_unsigned_short
231 impl_VLC_MediaControl_sound_get_volume( impl_POA_VLC_MediaControl * servant,
232                                         CORBA_Environment * ev );
233
234 static void
235 impl_VLC_MediaControl_sound_set_volume( impl_POA_VLC_MediaControl * servant,
236                                         const CORBA_unsigned_short volume,
237                                         CORBA_Environment * ev );
238
239 /*** epv structures ***/
240
241 static PortableServer_ServantBase__epv impl_VLC_MediaControl_base_epv = {
242     NULL,                       /* _private data */
243     ( gpointer ) & impl_VLC_MediaControl__destroy,      /* finalize routine */
244     NULL,                       /* default_POA routine */
245 };
246 static POA_VLC_MediaControl__epv impl_VLC_MediaControl_epv = {
247     NULL,                       /* _private */
248
249     ( gpointer ) & impl_VLC_MediaControl_get_media_position,
250
251     ( gpointer ) & impl_VLC_MediaControl_set_media_position,
252
253     ( gpointer ) & impl_VLC_MediaControl_start,
254
255     ( gpointer ) & impl_VLC_MediaControl_pause,
256
257     ( gpointer ) & impl_VLC_MediaControl_resume,
258
259     ( gpointer ) & impl_VLC_MediaControl_stop,
260
261     ( gpointer ) & impl_VLC_MediaControl_exit,
262
263     ( gpointer ) & impl_VLC_MediaControl_playlist_add_item,
264
265     ( gpointer ) & impl_VLC_MediaControl_playlist_clear,
266
267     ( gpointer ) & impl_VLC_MediaControl_playlist_get_list,
268
269     ( gpointer ) & impl_VLC_MediaControl_snapshot,
270
271     ( gpointer ) & impl_VLC_MediaControl_all_snapshots,
272
273     ( gpointer ) & impl_VLC_MediaControl_display_text,
274
275     ( gpointer ) & impl_VLC_MediaControl_get_stream_information,
276
277     ( gpointer ) & impl_VLC_MediaControl_sound_get_volume,
278
279     ( gpointer ) & impl_VLC_MediaControl_sound_set_volume,
280
281 };
282
283 /*** vepv structures ***/
284
285 static POA_VLC_MediaControl__vepv impl_VLC_MediaControl_vepv = {
286     &impl_VLC_MediaControl_base_epv,
287     &impl_VLC_MediaControl_epv,
288 };
289
290 /*** Stub implementations ***/
291
292 static VLC_MediaControl
293 impl_VLC_MediaControl__create( PortableServer_POA poa, CORBA_Environment * ev )
294 {
295     VLC_MediaControl retval;
296     impl_POA_VLC_MediaControl *newservant;
297     PortableServer_ObjectId *objid;
298
299     newservant = g_new0( impl_POA_VLC_MediaControl, 1 );
300     newservant->servant.vepv = &impl_VLC_MediaControl_vepv;
301     newservant->poa =
302         ( PortableServer_POA ) CORBA_Object_duplicate( (CORBA_Object ) poa, ev );
303     POA_VLC_MediaControl__init( (PortableServer_Servant ) newservant, ev );
304     /* Before servant is going to be activated all
305      * private attributes must be initialized.  */
306
307     /* ------ init private attributes here ------ */
308     newservant->mc = NULL;
309     /* ------ ---------- end ------------- ------ */
310
311     objid = PortableServer_POA_activate_object( poa, newservant, ev );
312     CORBA_free( objid );
313     retval = PortableServer_POA_servant_to_reference( poa, newservant, ev );
314
315     return retval;
316 }
317
318 static void
319 impl_VLC_MediaControl__destroy( impl_POA_VLC_MediaControl * servant,
320                                 CORBA_Environment * ev )
321 {
322     CORBA_Object_release( (CORBA_Object ) servant->poa, ev );
323
324     /* No further remote method calls are delegated to 
325      * servant and you may free your private attributes. */
326     /* ------ free private attributes here ------ */
327     /* ------ ---------- end ------------- ------ */
328
329     POA_VLC_MediaControl__fini( (PortableServer_Servant ) servant, ev );
330 }
331
332 /* END INSERT */
333
334 /* Beginning of the CORBA functions that we define */
335
336 /* Returns the current position in the stream. The returned value can
337    be relative or absolute ( according to PositionOrigin ) and the unit
338    is set by PositionKey */
339 static VLC_Position
340 impl_VLC_MediaControl_get_media_position( impl_POA_VLC_MediaControl * servant,
341                                           const VLC_PositionOrigin an_origin,
342                                           const VLC_PositionKey a_key,
343                                           CORBA_Environment * ev )
344 {
345     VLC_Position* retval = NULL;
346     mediacontrol_Position *p_pos;
347     mediacontrol_Exception *exception = NULL;
348
349     MC_TRY;
350     p_pos = mediacontrol_get_media_position( servant->mc, an_origin, a_key, exception );
351     MC_EXCEPT( *retval );
352
353     retval = corba_position_c_to_corba( p_pos );
354     free( p_pos );
355     return *retval;
356 }
357
358 /* Sets the media position */
359 static void
360 impl_VLC_MediaControl_set_media_position( impl_POA_VLC_MediaControl * servant,
361                                           const VLC_Position * a_position,
362                                           CORBA_Environment * ev )
363 {
364     mediacontrol_Position *p_pos;
365     mediacontrol_Exception *exception = NULL;
366
367     p_pos = corba_position_corba_to_c( a_position );
368   
369     MC_TRY;
370     mediacontrol_set_media_position( servant->mc, p_pos, exception );
371     MC_EXCEPT();
372     free( p_pos );
373
374     return;
375 }
376
377 /* Starts playing a stream */
378 static void
379 impl_VLC_MediaControl_start( impl_POA_VLC_MediaControl * servant,
380                              const VLC_Position * a_position, CORBA_Environment * ev )
381 {
382     mediacontrol_Position *p_pos;
383     mediacontrol_Exception *exception = NULL;
384
385     p_pos = corba_position_corba_to_c( a_position );
386   
387     MC_TRY;
388     mediacontrol_start( servant->mc, p_pos, exception );
389     MC_EXCEPT();
390
391     free( p_pos );
392     return;
393 }
394
395 static void
396 impl_VLC_MediaControl_pause( impl_POA_VLC_MediaControl * servant,
397                              const VLC_Position * a_position, CORBA_Environment * ev )
398 {
399     mediacontrol_Position *p_pos;
400     mediacontrol_Exception *exception = NULL;
401
402     p_pos = corba_position_corba_to_c( a_position );
403   
404     MC_TRY;
405     mediacontrol_pause( servant->mc, p_pos, exception );
406     MC_EXCEPT();
407
408     free( p_pos );
409     return;
410 }
411
412 static void
413 impl_VLC_MediaControl_resume( impl_POA_VLC_MediaControl * servant,
414                               const VLC_Position * a_position, CORBA_Environment * ev )
415 {
416     mediacontrol_Position *p_pos;
417     mediacontrol_Exception *exception = NULL;
418
419     p_pos = corba_position_corba_to_c( a_position );
420   
421     MC_TRY;
422     mediacontrol_resume( servant->mc, p_pos, exception );
423     MC_EXCEPT();
424
425     free( p_pos );
426     return;
427 }
428
429 static void
430 impl_VLC_MediaControl_stop( impl_POA_VLC_MediaControl * servant,
431                             const VLC_Position * a_position, CORBA_Environment * ev )
432 {
433     mediacontrol_Position *p_pos;
434     mediacontrol_Exception *exception = NULL;
435
436     p_pos = corba_position_corba_to_c( a_position );
437   
438     MC_TRY;
439     mediacontrol_pause( servant->mc, p_pos, exception );
440     MC_EXCEPT();
441
442     free( p_pos );
443     return;
444 }
445
446 static void
447 impl_VLC_MediaControl_exit( impl_POA_VLC_MediaControl * servant,
448                             CORBA_Environment * ev )
449 {
450     mediacontrol_exit( servant->mc );
451     return;
452 }
453
454 static void
455 impl_VLC_MediaControl_playlist_add_item( impl_POA_VLC_MediaControl * servant,
456                                          const CORBA_char * psz_file,
457                                          CORBA_Environment * ev )
458 {
459     mediacontrol_Exception *exception = NULL;
460   
461     MC_TRY;
462     mediacontrol_playlist_add_item( servant->mc, psz_file, exception );
463     MC_EXCEPT();
464
465     return;
466 }
467
468 static void
469 impl_VLC_MediaControl_playlist_clear( impl_POA_VLC_MediaControl * servant,
470                                       CORBA_Environment * ev )
471 {
472     mediacontrol_Exception *exception = NULL;
473   
474     MC_TRY;
475     mediacontrol_playlist_clear( servant->mc, exception );
476     MC_EXCEPT();
477
478     return;
479 }
480
481 static VLC_PlaylistSeq *
482 impl_VLC_MediaControl_playlist_get_list( impl_POA_VLC_MediaControl * servant,
483                                          CORBA_Environment * ev )
484 {
485     VLC_PlaylistSeq *retval = NULL;
486     mediacontrol_Exception *exception = NULL;
487     mediacontrol_PlaylistSeq* p_ps;
488     int i_index;
489    
490     MC_TRY;
491     p_ps = mediacontrol_playlist_get_list( servant->mc, exception );
492     MC_EXCEPT( retval );
493
494     retval = VLC_PlaylistSeq__alloc();
495     retval->_buffer = VLC_PlaylistSeq_allocbuf( p_ps->size );
496     retval->_length = p_ps->size;
497   
498     for( i_index = 0 ; i_index < p_ps->size ; i_index++ )
499     {
500         retval->_buffer[i_index] = CORBA_string_dup( p_ps->data[i_index] );
501     }
502     CORBA_sequence_set_release( retval, TRUE );
503   
504     mediacontrol_PlaylistSeq__free( p_ps );
505     return retval;
506 }
507
508 VLC_RGBPicture*
509 createRGBPicture( mediacontrol_RGBPicture* p_pic )
510 {
511     VLC_RGBPicture *retval;
512   
513     retval = VLC_RGBPicture__alloc();
514     if( retval )
515     {
516         retval->width  = p_pic->width;
517         retval->height = p_pic->height;
518         retval->type   = p_pic->type;
519         retval->date   = p_pic->date;
520       
521         retval->data._maximum = p_pic->size;
522         retval->data._length = p_pic->size;
523         retval->data._buffer = VLC_ByteSeq_allocbuf( p_pic->size );
524         memcpy( retval->data._buffer, p_pic->data, p_pic->size );
525         /* CORBA_sequence_set_release( &( retval->data ), FALSE ); */
526     }
527     return retval;
528 }
529
530 static VLC_RGBPicture *
531 impl_VLC_MediaControl_snapshot( impl_POA_VLC_MediaControl * servant,
532                                 const VLC_Position * a_position,
533                                 CORBA_Environment * ev )
534 {
535     VLC_RGBPicture *retval = NULL;
536     mediacontrol_RGBPicture* p_pic = NULL;
537     mediacontrol_Position *p_pos;
538     mediacontrol_Exception *exception = NULL;
539
540     p_pos = corba_position_corba_to_c( a_position );
541   
542     MC_TRY;
543     p_pic = mediacontrol_snapshot( servant->mc, p_pos, exception );
544     MC_EXCEPT( retval );
545   
546     retval = createRGBPicture( p_pic );
547     mediacontrol_RGBPicture__free( p_pic );
548     return retval;
549 }
550
551 static VLC_RGBPictureSeq *
552 impl_VLC_MediaControl_all_snapshots( impl_POA_VLC_MediaControl * servant,
553                                      CORBA_Environment * ev )
554 {
555     VLC_RGBPictureSeq *retval = NULL;
556     mediacontrol_RGBPicture** p_piclist = NULL;
557     mediacontrol_RGBPicture** p_tmp = NULL;
558     mediacontrol_Exception *exception = NULL;
559     int i_size = 0;
560     int i_index;
561   
562     MC_TRY;
563     p_piclist = mediacontrol_all_snapshots( servant->mc, exception );
564     MC_EXCEPT( retval );
565
566     for( p_tmp = p_piclist ; *p_tmp != NULL ; p_tmp++ )
567         i_size++;
568   
569     retval = VLC_RGBPictureSeq__alloc();
570     retval->_buffer = VLC_RGBPictureSeq_allocbuf( i_size );
571     retval->_length = i_size;
572
573     for( i_index = 0 ; i_index < i_size ; i_index++ )
574     {
575         mediacontrol_RGBPicture *p_pic = p_piclist[i_index];
576         VLC_RGBPicture *p_rgb;
577       
578         p_rgb = &( retval->_buffer[i_index] );
579       
580         p_rgb->width  = p_pic->width;
581         p_rgb->height = p_pic->height;
582         p_rgb->type   = p_pic->type;
583         p_rgb->date   = p_pic->date;
584       
585         p_rgb->data._maximum = p_pic->size;
586         p_rgb->data._length  = p_pic->size;
587         p_rgb->data._buffer  = VLC_ByteSeq_allocbuf( p_pic->size );
588         memcpy( p_rgb->data._buffer, p_pic->data, p_pic->size );
589         mediacontrol_RGBPicture__free( p_pic );
590     }
591   
592     free( p_piclist );
593     return retval;
594 }
595
596 static void
597 impl_VLC_MediaControl_display_text( impl_POA_VLC_MediaControl * servant,
598                                     const CORBA_char * message,
599                                     const VLC_Position * begin,
600                                     const VLC_Position * end,
601                                     CORBA_Environment * ev )
602 {
603     mediacontrol_Position *p_begin = NULL;
604     mediacontrol_Position *p_end = NULL;
605     mediacontrol_Exception *exception = NULL;
606
607     p_begin = corba_position_corba_to_c( begin );
608     p_end = corba_position_corba_to_c( end );
609     MC_TRY;
610     mediacontrol_display_text( servant->mc, message, p_begin, p_end, exception );
611     MC_EXCEPT();
612
613     free( p_begin );
614     free( p_end );
615     return;
616 }
617
618 static VLC_StreamInformation *
619 impl_VLC_MediaControl_get_stream_information( impl_POA_VLC_MediaControl *
620                                               servant, CORBA_Environment * ev )
621 {
622     mediacontrol_Exception *exception = NULL;
623     mediacontrol_StreamInformation *p_si = NULL;
624     VLC_StreamInformation *retval = NULL;
625
626     MC_TRY;
627     p_si = mediacontrol_get_stream_information( servant->mc, mediacontrol_MediaTime, exception );
628     MC_EXCEPT( retval );
629
630     retval = VLC_StreamInformation__alloc();
631     if( ! retval )
632     {
633         return NULL;
634     }
635
636     retval->streamstatus = p_si->streamstatus;
637     retval->url          = CORBA_string_dup( p_si->url );
638     retval->position     = p_si->position;
639     retval->length       = p_si->length;
640   
641     free( p_si->url );
642     free( p_si );
643     return retval;
644 }
645
646 static CORBA_unsigned_short
647 impl_VLC_MediaControl_sound_get_volume( impl_POA_VLC_MediaControl * servant,
648                                         CORBA_Environment * ev )
649 {
650     CORBA_short retval = 0;
651     mediacontrol_Exception *exception = NULL;
652   
653     MC_TRY;
654     retval = mediacontrol_sound_get_volume( servant->mc, exception );
655     MC_EXCEPT( retval );
656
657     return retval;
658 }
659
660 static void
661 impl_VLC_MediaControl_sound_set_volume( impl_POA_VLC_MediaControl * servant,
662                                         const CORBA_unsigned_short volume,
663                                         CORBA_Environment * ev )
664 {
665     mediacontrol_Exception *exception = NULL;
666   
667     MC_TRY;
668     mediacontrol_sound_set_volume( servant->mc, volume, exception );
669     MC_EXCEPT();
670 }
671
672 /* ( Real ) end of the CORBA code generated in Mediacontrol-skelimpl.c */
673
674 /*****************************************************************************
675  * Local prototypes.
676  *****************************************************************************/
677 static int  Open         ( vlc_object_t * );
678 static void Close        ( vlc_object_t * );
679 static void Run          ( intf_thread_t * );
680
681 /*****************************************************************************
682  * Module descriptor
683  *****************************************************************************/
684 vlc_module_begin();
685 add_category_hint( N_( "Corba control" ), NULL, VLC_FALSE );
686
687 set_description( _( "corba control module" ) );
688 set_capability( "interface", 10 );
689 add_integer( "corba-reactivity", 5000, NULL, "Internal reactivity factor", "Internal reactivity factor ( gtk timeout is INTF_IDLE_SLEEP / factor )", VLC_TRUE );
690 set_callbacks( Open, Close );
691 vlc_module_end();
692
693 /*****************************************************************************
694  * intf_Open: initialize and create stuff
695  *****************************************************************************/
696 static int Open( vlc_object_t *p_this )
697 {
698     intf_thread_t *p_intf = ( intf_thread_t * )p_this;
699
700     /* Allocate instance and initialize some members */
701     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
702     if( p_intf->p_sys == NULL )
703     {
704         msg_Err( p_intf, "Out of memory" );
705         return VLC_ENOMEM;
706     }
707
708     /* Initialize the fields of the p_intf struct */
709     p_intf->pf_run = Run;
710
711     p_intf->p_sys->mc = NULL;
712     p_intf->p_sys->orb = NULL;
713     p_intf->p_sys->corbaloop = NULL;
714
715     return VLC_SUCCESS;
716 }
717
718 /*****************************************************************************
719  * intf_Close: destroy interface
720  *****************************************************************************/
721 static void Close( vlc_object_t *p_this )
722 {
723     intf_thread_t *p_intf = ( intf_thread_t * )p_this;
724     CORBA_Environment*        ev = NULL;
725
726     ev = CORBA_exception__alloc();
727     CORBA_ORB_shutdown( p_intf->p_sys->orb, FALSE, ev );
728     handle_exception_no_servant( p_intf, "Error in Close" );
729
730     /* Destroy structure */
731     free( p_intf->p_sys );
732 }
733
734 /*
735   Function called regularly to handle various tasks( mainly CORBA calls )
736 */
737 static gboolean Manage( gpointer p_interface )
738 {
739     intf_thread_t *p_intf = ( intf_thread_t* )p_interface;
740     CORBA_boolean b_work_pending;
741     CORBA_Environment* ev;
742
743     ev = CORBA_exception__alloc();
744
745     /* CORBA */
746     b_work_pending = CORBA_ORB_work_pending( p_intf->p_sys->orb, ev );
747     if( ev->_major != CORBA_NO_EXCEPTION )
748     {
749         msg_Err( p_intf, "Exception in CORBA events check loop" );
750         return FALSE;
751     }
752   
753     vlc_mutex_lock( &p_intf->change_lock );
754
755     if( b_work_pending )
756         CORBA_ORB_perform_work( p_intf->p_sys->orb, ev );
757   
758     if( p_intf->b_die )
759     {
760         vlc_mutex_unlock( &p_intf->change_lock );
761         CORBA_ORB_shutdown( p_intf->p_sys->orb, TRUE, ev );
762         g_main_loop_quit( p_intf->p_sys->corbaloop );
763         /* Just in case */
764         return( TRUE );
765     }
766
767     vlc_mutex_unlock( &p_intf->change_lock );
768
769     return TRUE;
770 }
771
772 /*****************************************************************************
773  * Run: main loop
774  *****************************************************************************
775  * this part of the interface is in a separate thread so that we can call
776  * g_main_loop_run() from within it without annoying the rest of the program.
777  *****************************************************************************/
778 static void Run( intf_thread_t *p_intf )
779 {
780     CORBA_Environment*        ev = NULL;
781     PortableServer_POA        root_poa;
782     PortableServer_POAManager root_poa_manager;
783     guint                     i_event_source;
784     CORBA_char*               psz_objref;
785     impl_POA_VLC_MediaControl *servant = NULL;
786     VLC_MediaControl          corba_instance;
787     mediacontrol_Instance     *mc_instance;
788     mediacontrol_Exception    *exception = NULL;
789     int i_argc = 1;
790     char* ppsz_argv[] = { "mc" };
791     int i_reactivity;
792
793     ev = CORBA_exception__alloc();
794
795     p_intf->p_sys->orb = CORBA_ORB_init( &i_argc, ppsz_argv, "orbit-local-orb", ev );
796
797     /* Should be cleaner this way ( cf
798        http://www.fifi.org/doc/gnome-dev-doc/html/C/orbitgtk.html ) but it
799        functions well enough in the ugly way so that I do not bother
800        cleaning it */
801     /* p_intf->p_sys->orb = gnome_CORBA_init ( "VLC", NULL, &argc, &argv, 0, NULL, ev ); */
802
803     handle_exception_no_servant( p_intf, "Exception during CORBA_ORB_init" );
804
805     root_poa = ( PortableServer_POA )CORBA_ORB_resolve_initial_references( p_intf->p_sys->orb, "RootPOA", ev );
806     handle_exception( "Exception during RootPOA initialization" );
807
808     corba_instance = impl_VLC_MediaControl__create( root_poa, ev );
809     handle_exception( "Exception during MediaControl initialization" );
810
811     servant = ( impl_POA_VLC_MediaControl* )PortableServer_POA_reference_to_servant( root_poa, corba_instance, ev );
812     handle_exception( "Exception during MediaControl access" );
813
814     MC_TRY;
815     mc_instance = mediacontrol_new_from_object((vlc_object_t* )p_intf, exception );
816     MC_EXCEPT();
817
818     p_intf->p_sys->mc = mc_instance;
819
820     servant->p_intf = p_intf;
821     servant->mc = p_intf->p_sys->mc;
822
823     psz_objref = CORBA_ORB_object_to_string( p_intf->p_sys->orb, corba_instance, ev );
824     handle_exception( "Exception during IOR generation" );
825
826     msg_Warn( p_intf, "MediaControl IOR :" );
827     msg_Warn( p_intf, psz_objref );
828
829     /* We write the IOR in a file. */
830     {
831         FILE* fp;
832         fp = fopen( VLC_IOR_FILE, "w" );
833         if( fp == NULL )
834         {
835             msg_Err( p_intf, "Cannot write the IOR to %s ( %d ).", VLC_IOR_FILE, errno );
836         }
837         else
838         {
839             fprintf( fp, "%s", psz_objref );
840             fclose( fp );
841             msg_Warn( p_intf, "IOR written to %s", VLC_IOR_FILE );
842         }
843     }
844   
845     root_poa_manager = PortableServer_POA__get_the_POAManager( root_poa, ev );
846     handle_exception( "Exception during POAManager resolution" );
847
848     PortableServer_POAManager_activate( root_poa_manager, ev );
849     handle_exception( "Exception during POAManager activation" );
850
851     msg_Info( p_intf, "corba remote control interface initialized" );
852
853     /*
854     // Tentative de gestion du nommage...
855     {
856     CosNaming_NamingContext name_service;
857     CosNaming_NameComponent name_component[3] = {{"GNOME", "subcontext"},
858     {"Servers", "subcontext"},
859     {"vlc", "server"} };
860     CosNaming_Name name = {3, 3, name_component, CORBA_FALSE};
861
862     name_service = CORBA_ORB_resolve_initial_references( p_intf->p_sys->orb,
863     "NameService",
864     ev );
865     handle_exception( "Error: could not get name service: %s\n",
866     CORBA_exception_id( ev ) );
867     msg_Warn( p_intf, "Name service OK" );
868
869     CosNaming_NamingContext_bind( name_service, &name, p_intf->p_sys->mc, ev );
870     handle_exception( "Error: could not register object: %s\n",
871     CORBA_exception_id( ev ) );
872     }
873     */
874
875     /* The time factor should be 1/1000 but it is a little too
876        slow. Make it 1/10000 */
877     i_reactivity = config_GetInt( p_intf, "corba-reactivity" );
878     i_event_source = g_timeout_add( INTF_IDLE_SLEEP / i_reactivity, Manage, p_intf );
879     p_intf->p_sys->corbaloop = g_main_loop_new( NULL, FALSE );
880     g_main_loop_run( p_intf->p_sys->corbaloop );
881
882     /* Cleaning */
883     g_source_remove( i_event_source );
884     unlink( VLC_IOR_FILE );
885
886     /* Make sure we exit ( In case other interfaces have been spawned ) */
887     mediacontrol_exit( p_intf->p_sys->mc );
888
889     return;
890 }