b3aed4e6a9534c0d3fa7addc47fdee7043fd3505
[glsdk/dual-decode.git] / src / gui.c
1 /*
2  *
3  *  Redistribution and use in source and binary forms, with or without
4  *  modification, are permitted provided that the following conditions
5  *  are met:
6  *
7  *  *  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *
10  *  *  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  *  *  Neither the name of Texas Instruments Incorporated nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *  Contact information for paper mail:
31  *  Texas Instruments
32  *  Post Office Box 655303
33  *  Dallas, Texas 75265
34  *  Contact information:
35  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm
36  *  ?DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
37  *  ============================================================================
38  *
39  */
41 /**
42  * @file                gui.c
43  *
44  * @brief               Defines the functions exported by the GUI.
45  *                              Also, defines the static functions and the callback funtions
46  */
47 #include <string.h>
48 #include <linux/limits.h>
49 #include <gtk/gtk.h>
50 #include <gdk/gdkx.h>                                                           
51 #include <gst/interfaces/xoverlay.h>  
53 #include <gui.h>
54 #include <common.h>
55 #include <gst-controller.h>
57 /******************************************************************************
58  *      Static variables declaration
59  ******************************************************************************/
60 static GUIWindow *window[]              = {NULL, NULL};
61 static Pipeline *pipes[]                = {NULL, NULL};
62 static GtkWidget *logWindow[]   = {NULL, NULL};
63 static GtkWidget *helpWindow    = NULL;
66 /******************************************************************************
67  *      Static functions declaration
68  ******************************************************************************/
69 static gint setAbsolutePathname (gchar *file, gchar **uri)  ;
70 static void setControlMode (GUIWindow *thisWindow,gint modeFlag,gint activeFlag);
71 static void setControlActive (GUIWindow *window, gboolean activeFlag);
72 static void setup();
73 static void setDecodeSwitch (gint decodeSwitch);
74 static GtkWidget *createLogWindow();
75 static GtkWidget *createHelpWindow();
76 static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name);
77 static void setWindowSizeLocation();
78 static GUIWindow *createWindow();
80 static gboolean cbOpenClicked (GtkWidget *widget, gpointer data);
81 static gboolean cbPlayClicked (GtkWidget *widget, gpointer data);
82 static gboolean cbPauseClicked (GtkWidget *widget, gpointer data);
83 static gboolean cbStopClicked (GtkWidget *widget, gpointer data);
84 static gboolean cbForwardClicked (GtkWidget *widget, gpointer data);
85 static gboolean cbRewindClicked (GtkWidget *widget, gpointer data);
86 static gboolean cbWindowClosed (GtkWidget *widget, gpointer data);
87 static gboolean cbHelpClicked (GtkWidget *widget, gpointer data);
88 static gboolean cbTimerInterval (gpointer data);
89 static gboolean cbSeekValueChanged (GtkWidget *widget, gpointer data);
90 static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data);
91 static gboolean cbHelpClosed (GtkWidget *widget, gpointer data);
92 //static void logGUI (GtkWidget *logWindow, gchar *format, ...); 
94 static gint setAbsolutePathname (gchar *file, gchar **uri)                             
95 {                                                                               
96     gchar *realPath = NULL;                                                     
97     gint ret        = ERR_SUCCESS;                                              
98                                                                                 
99     if(NULL == uri){                                                            
100         return ERR_INVALIDPARAM;                                                
101     }                                                                           
102                                                                                 
103     if(NULL == file){                                                           
104         /*A BUG Here*/                                                          
105         g_printerr("BUG: file: " __FILE__ " line: %d" "\n", __LINE__);          
106         return ERR_BUG;                                                         
107     }                                                                           
108                                                                                 
109     *uri = (gchar *) g_malloc (sizeof(gchar) * PATH_MAX_LEN);                   
110     realPath = realpath (file, realPath);                                       
111     if (NULL == realPath) {                                                     
112         /*TODO: a debug trace here*/                                            
113         g_printerr ("File %s not found\n", file);                               
114         ret = ERR_FILENOTFOUND;                                                 
115         goto destroy;                                                           
116     }                                                                           
117     g_snprintf(*uri,PATH_MAX_LEN,"file://%s",realPath);                         
118                                                                                 
119     goto last;                                                                  
120                                                                                 
121 destroy:                                                                        
122     g_free(*uri);                                                               
123     *uri=NULL;                                                                  
124 last:                                                                           
125     free (realPath);                                                            
126     return ret;                                                                 
127 }        
128 /******************************************************************************
129  *      Callback functions definition
130  ******************************************************************************/
132 /*Timer Interval Callback Function*/
133 static gboolean cbTimerInterval(gpointer data)
135         gdouble seekScaleValue = 0.0;
136         gchar *timeLabelText = TIME_LABEL_ORIGIN;
137         GUIWindow *thisWindow = (GUIWindow *)data;
138         gboolean ret = TRUE;
139     
140     //g_print ("IN timer");
141         if (DECODE_MODE_SINGLE == decodeMode){
142                 ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
143                                 &seekScaleValue,
144                                 &timeLabelText);
145         //g_print ("Seek Value %f", seekScaleValue);
147                 g_signal_handler_block (window[DECODER_INDEX_SINGLE]->seekScale,
148                                 window[DECODER_INDEX_SINGLE]->seekSignal);
149         gtk_range_set_value (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
150                                 seekScaleValue);
151                 gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
152                                 timeLabelText);
153                 g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
154                                 window[DECODER_INDEX_SINGLE]->seekSignal);
156                 g_signal_handler_block(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
157                                 window[DECODER_INDEX_DOUBLE]->seekSignal);
158                 gtk_range_set_value(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
159                                 seekScaleValue);
160                 gtk_label_set_text(GTK_LABEL (window[DECODER_INDEX_DOUBLE]->timeLabel),
161                                 timeLabelText);
162                 g_signal_handler_unblock(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
163                                 window[DECODER_INDEX_DOUBLE]->seekSignal);
164         }else{
165                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
166                         ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
167                                         &seekScaleValue,
168                                         &timeLabelText);
169                         
170             g_signal_handler_block(GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
171                                         window[DECODER_INDEX_SINGLE]->seekSignal);
172                         gtk_range_set_value(GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
173                                         seekScaleValue);
174                         gtk_label_set_text(GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
175                                         timeLabelText);
176                         g_signal_handler_unblock(GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
177                                         window[DECODER_INDEX_SINGLE]->seekSignal);
178                 }else{
179                         ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_DOUBLE],
180                                         &seekScaleValue,
181                                         &timeLabelText);
183                         g_signal_handler_block(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
184                                         window[DECODER_INDEX_DOUBLE]->seekSignal);
185                         gtk_range_set_value(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
186                                         seekScaleValue);
187                         gtk_label_set_text (GTK_LABEL(window[DECODER_INDEX_DOUBLE]->timeLabel),
188                                         timeLabelText);
189                         g_signal_handler_unblock(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
190                                         window[DECODER_INDEX_DOUBLE]->seekSignal);
191                 }
192         }
193         if(ret){
194                 g_free(timeLabelText);
195         }
196     return ret;
199 /*Seek Scale Changed Value Callback Function*/
200 static gboolean cbSeekValueChanged(GtkWidget *widget, gpointer data)
202     gboolean ret = TRUE;
203     GstFormat format = GST_FORMAT_TIME; 
204     gint64 duration = 0;
205     gint seekPoint = 0;
206     gdouble percent = gtk_range_get_value ((GtkRange *)widget);
207     g_print ("PERCENT %f\n", percent);
208     GUIWindow *thisWindow = (GUIWindow *)data; 
210     g_print ("IN SEEK VALUE CHANGED\n");
211     if (DECODE_MODE_SINGLE == decodeMode){
212                                                                                     
213         gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
214                                     &format,&duration);
215         seekPoint = (gint64) (duration * percent/ (gdouble)100);
216         g_print ("SEEK POINT %d\n", seekPoint);
217         ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);
218     }
219     else{                                                                      
220         if(window[DECODER_INDEX_SINGLE] == thisWindow){    
221             gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
222                                         &format,&duration);              
223             seekPoint = (gint64) (duration * percent/ (gdouble)100);
224             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);
225         } 
226         else {
227             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,
228                                        &format,&duration);              
229             seekPoint = (gint64) (duration * percent/ (gdouble)100);
230             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
231         }
232     }   
233     
234         return ret;
237 /*Open Button Clicked Callback Function*/
238 static gboolean cbOpenClicked(GtkWidget *widget, gpointer data)
240     gboolean ret = TRUE;
241     gchar *uri = NULL;
242     gchar *file = NULL;
243         GUIWindow *thisWindow = (GUIWindow *)data;
244         GtkWidget *fileChooser = gtk_file_chooser_dialog_new(
245                         "Open",
246                         GTK_WINDOW(thisWindow->window),
247                         GTK_FILE_CHOOSER_ACTION_OPEN,
248                         GTK_STOCK_OPEN,
249                         GTK_RESPONSE_OK,
250                         GTK_STOCK_CANCEL,
251                         GTK_RESPONSE_CANCEL,
252                         NULL);
253         gtk_window_set_modal(GTK_WINDOW(fileChooser),TRUE);
254         gtk_window_set_destroy_with_parent(GTK_WINDOW(fileChooser),TRUE);
255         gtk_widget_set_sensitive(thisWindow->window,FALSE);
256         
257         if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(fileChooser))){
258                 
259                 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser));
260                 
261         if (ERR_SUCCESS != setAbsolutePathname (file, &uri)){
262             ret = FALSE;
263             goto last;
264         }
265         //g_print ("FILE URI :%s", uri);
266                 if(DECODE_MODE_SINGLE == decodeMode){
267             filename[DECODER_INDEX_SINGLE] = uri;
268                         setControlMode(window[DECODER_INDEX_SINGLE],
269                                         CONTROL_MODE_PLAYING,
270                                         window[DECODER_INDEX_SINGLE]->activeFlag);
271                         setControlMode(window[DECODER_INDEX_DOUBLE],
272                                         CONTROL_MODE_PLAYING,
273                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
274                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
275                                         filename[DECODER_INDEX_SINGLE],
276                                         SEEK_START);
277                 }else{
278             filename[DECODER_INDEX_SINGLE] = uri;
279                         if(window[DECODER_INDEX_SINGLE] == thisWindow){
280                                 setControlMode(window[DECODER_INDEX_SINGLE],
281                                                 CONTROL_MODE_PLAYING,
282                                                 window[DECODER_INDEX_SINGLE]->activeFlag);
283                                 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
284                                                 filename[DECODER_INDEX_SINGLE],
285                                                 SEEK_START);
286                         }else{
287                 filename[DECODER_INDEX_DOUBLE] = uri;   
288                                 setControlMode(window[DECODER_INDEX_DOUBLE],
289                                                 CONTROL_MODE_PLAYING,
290                                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
291                                 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
292                                                 filename[DECODER_INDEX_DOUBLE],
293                                                 SEEK_START);
294                         }
295                 }
296         }
297         if (GTK_IS_WIDGET (fileChooser))
298                 gtk_widget_destroy (fileChooser);
300         if( GTK_IS_WIDGET (thisWindow->window))
301                 gtk_widget_set_sensitive (thisWindow->window,TRUE);
303 last:    return ret;
306 /*Play Button Clicked Callback Function*/
307 static gboolean cbPlayClicked(GtkWidget *widget, gpointer data)
309         gboolean ret = TRUE;
310     GUIWindow *thisWindow = (GUIWindow *)data;
312         if(DECODE_MODE_SINGLE == decodeMode){
313                 setControlMode(window[DECODER_INDEX_SINGLE],
314                                 CONTROL_MODE_PLAYING,
315                                 window[DECODER_INDEX_SINGLE]->activeFlag);
316                 setControlMode(window[DECODER_INDEX_DOUBLE],
317                                 CONTROL_MODE_PLAYING,
318                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
319                 if(GST_STATE_PAUSED == 
320                                 DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
321                         DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
322                 }else{
323                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
324                                         filename[DECODER_INDEX_SINGLE],
325                                         SEEK_START);
326              }
327         }else{
328                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
329                         setControlMode (window[DECODER_INDEX_SINGLE],
330                                         CONTROL_MODE_PLAYING,
331                                         window[DECODER_INDEX_SINGLE]->activeFlag);
332                         if (GST_STATE_PAUSED == 
333                                         DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
334                                 DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
335                         }else if (GST_STATE_READY == 
336                          DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
337                g_print ("\nPipeline state is READY\n");
338                DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], window[DECODER_INDEX_SINGLE]->sink, NULL); 
339                DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], filename[0],0);
340                //DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], 0);
341             }
343              else {
344                                   DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
345                                                 filename[DECODER_INDEX_SINGLE],
346                                                 SEEK_START);
347                         }
348                 }else{
349                         setControlMode(window[DECODER_INDEX_DOUBLE],
350                                         CONTROL_MODE_PLAYING,
351                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
352                         if(GST_STATE_PAUSED == 
353                                         DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
354                                 DualDecode_resumeMedia(pipes[DECODER_INDEX_DOUBLE]);
355                         }
356             else if (GST_STATE_READY ==                                        
357                          DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
358                DualDecode_resumeMedia (pipes[DECODER_INDEX_DOUBLE]);            
359                //DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], 0);         
360             }   
362             else{
363                                 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
364                                                 filename[DECODER_INDEX_DOUBLE],
365                                                 SEEK_START);
366                         }
367                 }
368         }
369     return ret;
372 /*Pause Button Clicked Callback Function*/
373 static gboolean cbPauseClicked(GtkWidget *widget, gpointer data)
375         gboolean ret = TRUE;
376     GUIWindow *thisWindow = (GUIWindow *)data;
378         if(DECODE_MODE_SINGLE == decodeMode){
379                 setControlMode(window[DECODER_INDEX_SINGLE],
380                                 CONTROL_MODE_PAUSED,
381                                 window[DECODER_INDEX_SINGLE]->activeFlag);
382                 setControlMode(window[DECODER_INDEX_DOUBLE],
383                                 CONTROL_MODE_PAUSED,
384                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
385                 DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
386         }else{
387                 if(window[DECODER_INDEX_SINGLE] == thisWindow){
388                         setControlMode(window[DECODER_INDEX_SINGLE],
389                                         CONTROL_MODE_PAUSED,
390                                         window[DECODER_INDEX_SINGLE]->activeFlag);
391                         DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
392                 }else{
393                         setControlMode(window[DECODER_INDEX_DOUBLE],
394                                         CONTROL_MODE_PAUSED,
395                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
396                         DualDecode_pauseMedia(pipes[DECODER_INDEX_DOUBLE]);
397                 }
398         }
399     return ret;
402 /*Stop Button Clicked Callback Function*/
403 static gboolean cbStopClicked(GtkWidget *widget, gpointer data)
405         gboolean ret = TRUE;
406     GUIWindow *thisWindow = (GUIWindow *)data;
407    
409         if (DECODE_MODE_SINGLE == decodeMode){
410                 setControlMode (window[DECODER_INDEX_SINGLE],
411                                 CONTROL_MODE_STOPPED,
412                                 window[DECODER_INDEX_SINGLE]->activeFlag);
413                 setControlMode (window[DECODER_INDEX_DOUBLE],
414                                 CONTROL_MODE_STOPPED,
415                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
416                 DualDecode_stopMedia (pipes[DECODER_INDEX_SINGLE]);
417         }else{
418                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
419                         setControlMode(window[DECODER_INDEX_SINGLE],
420                                         CONTROL_MODE_STOPPED,
421                                         window[DECODER_INDEX_SINGLE]->activeFlag);
422                         DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
423                 }else{
424                         setControlMode (window[DECODER_INDEX_DOUBLE],
425                                         CONTROL_MODE_STOPPED,
426                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
427                         DualDecode_stopMedia (pipes[DECODER_INDEX_DOUBLE]);
428                 }
429         }
430     return ret;
432 static gboolean cbForwardClicked(GtkWidget *widget, gpointer data)                 
433 {                                                                               
434     gboolean ret = TRUE;                                                        
435     GstFormat format = GST_FORMAT_TIME;                                         
436     gint64 duration = 0;                                                        
437     gint64 seekPoint = 0;                                                         
438     GUIWindow *thisWindow = (GUIWindow *)data;               
439     gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));                   
440                                                                                 
441     g_print ("IN FORWARD CLICKED\n");                                        
442     if (DECODE_MODE_SINGLE == decodeMode){                                      
443                                                                                 
444         gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,          
445                                     &format,&duration);                         
446         seekPoint =  (duration * percent/ (gdouble)100)+ FORWARD;                
447         g_print ("SEEK POINT %d\n", seekPoint);                                 
448         ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);     
449     }                                                                           
450     else{                                                                       
451         if(window[DECODER_INDEX_SINGLE] == thisWindow){                         
452             gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
453                                         &format, &duration);                     
454             seekPoint =  (duration * percent/ (gdouble)100) + FORWARD;
455             g_print ("SEEK POINT %d\n", seekPoint);            
456             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint); 
457         }                                                                       
458         else {                                                                  
459             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,       
460                                        &format,&duration);                      
461             seekPoint = (duration * percent/ (gdouble)100)+ FORWARD;            
462             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
463         }                                                                       
464     }                                                                           
465                                                                                 
466         return ret; 
467 }                                                                                
468 static gboolean cbRewindClicked(GtkWidget *widget, gpointer data)                 
470     gboolean ret = TRUE;                                                        
471     GstFormat format = GST_FORMAT_TIME;                                         
472     gint64 duration = 0;                                                        
473     gint64 seekPoint = 0;                                                       
474     GUIWindow *thisWindow = (GUIWindow *)data;                                  
475     gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));
476                                                                                 
477     g_print ("IN FORWARD CLICKED\n");                                           
478     if (DECODE_MODE_SINGLE == decodeMode){                                      
479                                                                                 
480         gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,          
481                                     &format,&duration);                         
482         seekPoint =  (duration * percent/ (gdouble)100) - REWIND;               
483         g_print ("SEEK POINT %d\n", seekPoint);
484         seekPoint = (seekPoint < 0) ? 0 : seekPoint;                                 
485         ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);     
486     }                                                                           
487     else{                                                                       
488         if(window[DECODER_INDEX_SINGLE] == thisWindow){                         
489             gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
490                                         &format, &duration);                    
491             seekPoint =  (duration * percent/ (gdouble)100) - REWIND;          
492             g_print ("SEEK POINT %d\n", seekPoint);
493             seekPoint = (seekPoint < 0) ? 0 : seekPoint;                             
494             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint); 
495         }                                                                       
496         else {                                                                  
497             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,       
498                                        &format,&duration);                      
499             seekPoint = (duration * percent/ (gdouble)100) - REWIND;    
500             seekPoint = (seekPoint < 0) ? 0 : seekPoint;        
501             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
502         }                                                                       
503     }                                                                           
504                                                                                 
505         return ret;                                                                                  
506 }    
507 static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data)
509     gboolean ret = TRUE;
510     gboolean noFile = FALSE;
511     GUIWindow *thisWindow = (GUIWindow *) data;
512     gint otherWindowIndex = 0;
513     gint thisWindowIndex = 0;
515     /*No file is given yet to play. Application may be just started. */
516     if (NULL == filename[DECODER_INDEX_SINGLE])
517         noFile = TRUE;
519          
520         
522     if (thisWindow == window[DECODER_INDEX_SINGLE]){
523         thisWindowIndex = DECODER_INDEX_SINGLE;
524         otherWindowIndex = DECODER_INDEX_DOUBLE;
525     }
526     else {
527         otherWindowIndex = DECODER_INDEX_SINGLE;
528         thisWindowIndex = DECODER_INDEX_DOUBLE;
529     }
531     switch (decodeMode)
532     {
533       case DECODE_MODE_SINGLE :  
534           setControlMode (window[otherWindowIndex], window[otherWindowIndex]->modeFlag, 
535                           CONTROL_MODE_ACTIVE);
536           setControlMode (thisWindow, thisWindow->modeFlag,       
537                           CONTROL_MODE_ACTIVE);
539           if (FALSE == noFile) {
540           ret = DualDecode_singleToDual (pipes,
541                                          window[otherWindowIndex]->sink,
542                                          thisWindowIndex, otherWindowIndex, 
543                                          filename[DECODER_INDEX_SINGLE]);
544           }
545           decodeMode = DECODE_MODE_DUAL;
546           setDecodeSwitch(DECODE_MODE_SINGLE);
547           break;
549       case DECODE_MODE_DUAL :      
550           setControlMode (window[otherWindowIndex], thisWindow->modeFlag, 
551                           CONTROL_MODE_INACTIVE);  
553           if (FALSE == noFile) {
554           ret = DualDecode_dualToSingle (pipes,
555                                          window[otherWindowIndex]->sink,        
556                                          thisWindowIndex, otherWindowIndex);
557            }
558            decodeMode = DECODE_MODE_SINGLE; 
559            setDecodeSwitch(DECODE_MODE_DUAL);  
560           
561           break;
562     } 
565     return ret;
567 /*Window Close Callback Function*/
568 static gboolean cbWindowClosed(GtkWidget *widget, gpointer data){
569         DualDecode_exitApplication();
570     return TRUE;
573 static gboolean cbHelpClicked (GtkWidget *widget, gpointer data){
574     g_print ("HELP BUTTON CLICKED\n");
575     gtk_widget_show (helpWindow);
576     return TRUE;
579 static gboolean cbHelpClosed (GtkWidget *widget, gpointer data){
580     g_print ("IN HELP CLOSED\n");
581     gtk_widget_hide (helpWindow);
582     return TRUE;
584 /******************************************************************************
585  *      static utility functions definition
586  ******************************************************************************/
587 static void setControlActive(GUIWindow *window, gboolean activeFlag)
589         gtk_widget_set_sensitive(window->playButton,activeFlag);
590         gtk_widget_set_sensitive(window->pauseButton,activeFlag);
591         gtk_widget_set_sensitive(window->stopButton,activeFlag);
592         gtk_widget_set_sensitive(window->rewindButton,activeFlag);
593         gtk_widget_set_sensitive(window->forwardButton,activeFlag);
594         gtk_widget_set_sensitive(window->openButton,activeFlag);
595         gtk_widget_set_sensitive(window->seekScale,activeFlag);
596     gtk_widget_set_sensitive (window->switchButton, activeFlag);
597     
600 static void setControlMode(GUIWindow *thisWindow,
601                 gint modeFlag,
602                 gint activeFlag)
604         setControlActive(thisWindow, activeFlag);
605         if(activeFlag){
606                 switch(modeFlag){
607                         case CONTROL_MODE_NO_FILE:
608                                 gtk_widget_set_sensitive(thisWindow->playButton,FALSE);
609                                 gtk_widget_set_sensitive(thisWindow->pauseButton,FALSE);
611                                 gtk_widget_set_sensitive(thisWindow->stopButton,FALSE);
612                                 gtk_widget_set_sensitive(thisWindow->rewindButton,FALSE);
613                                 gtk_widget_set_sensitive(thisWindow->forwardButton,FALSE);
614                                 gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
616                                 break;
617                         case CONTROL_MODE_PLAYING:
618                                 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
619                                 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
621                                 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
622                                 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
623                                 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
624                                 gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
626                                 break;
627                         case CONTROL_MODE_STOPPED:
628                                 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
629                                 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
631                                 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
632                                 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
633                                 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
634                                 gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
636                                 break;
637                         case CONTROL_MODE_PAUSED:
638                                 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
639                                 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
641                                 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
642                                 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
643                                 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
644                                 gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
646                                 break;
647                 }
648         }
649         switch(modeFlag){
650                 case CONTROL_MODE_NO_FILE:
651                         gtk_widget_show(thisWindow->playButton);
652                         gtk_widget_hide(thisWindow->pauseButton);
654                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
655                                         LABEL_TEXT_NO_FILE);
656                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
657                                         TIME_LABEL_ORIGIN);
658                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
659                                 g_source_remove(thisWindow->timerSignal);
660                                 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
661                         }
662                         break;
663                 case CONTROL_MODE_PLAYING:
664                         gtk_widget_show(thisWindow->pauseButton);
665                         gtk_widget_hide(thisWindow->playButton);
667                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
668                                         LABEL_TEXT_PLAYING);
669                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
670                                         TIME_LABEL_ORIGIN);
672                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
673                                 g_source_remove(thisWindow->timerSignal);
674             }
675                         thisWindow->timerSignal = g_timeout_add(TIMER_INTERVAL,
676                                                 cbTimerInterval,
677                                                 thisWindow); 
678                         
679                         break;
680                 case CONTROL_MODE_STOPPED:
681                         gtk_widget_show(thisWindow->playButton);
682                         gtk_widget_hide(thisWindow->pauseButton);
684                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
685                                         LABEL_TEXT_STOPPED);
686                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
687                                         TIME_LABEL_ORIGIN);
689                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
690                                 g_source_remove(thisWindow->timerSignal);
691                                 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
692                         }
693                         break;
694                 case CONTROL_MODE_PAUSED:
695                         gtk_widget_show(thisWindow->playButton);
696                         gtk_widget_hide(thisWindow->pauseButton);
698                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
699                                         LABEL_TEXT_PAUSED);
700                         break;
702         }
703         thisWindow->modeFlag = modeFlag;
704         thisWindow->activeFlag = activeFlag;
707 static void setDecodeSwitch(gint decodeSwitch)
709         switch (decodeSwitch){
710                 case DECODE_MODE_SINGLE:
711                         gtk_button_set_label(
712                                         GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
713                                         SWITCH_TEXT_SINGLE);
714                         gtk_button_set_label(
715                                         GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
716                                         SWITCH_TEXT_SINGLE);
717                         break;
718                 case DECODE_MODE_DUAL:
719                         gtk_button_set_label(
720                                         GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
721                                         SWITCH_TEXT_DUAL);
722                         gtk_button_set_label(
723                                         GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
724                                         SWITCH_TEXT_DUAL);
725         }
728 static void setup()
731     g_print ("SINK TO BE USED %s\n", sink);
732         gtk_widget_show_all (window[DECODER_INDEX_SINGLE]->window);
733         gtk_widget_show_all (window[DECODER_INDEX_DOUBLE]->window);
735     window[DECODER_INDEX_SINGLE]->sink = createImageSinkFromWindow (            
736                                         window[DECODER_INDEX_SINGLE]->drawArea, 
737                                         "windowsink0"); 
739     window[DECODER_INDEX_DOUBLE]->sink = createImageSinkFromWindow (           
740                                         window[DECODER_INDEX_DOUBLE]->drawArea, 
741                                         "windowsink1"); 
743     /*If any of the sinks is NULL the application exits*/
745     if (NULL == window[DECODER_INDEX_SINGLE]->sink || 
746         NULL == window[DECODER_INDEX_DOUBLE]->sink) {
747             DualDecode_exitApplication();
748     
749     }
750         switch(decodeMode){
751                 case DECODE_MODE_NONE:
752                         setControlMode(window[DECODER_INDEX_SINGLE],
753                                         CONTROL_MODE_NO_FILE,
754                                         CONTROL_MODE_ACTIVE);
755                         setControlMode(window[DECODER_INDEX_DOUBLE],
756                                         CONTROL_MODE_NO_FILE,
757                                         CONTROL_MODE_ACTIVE);
758              DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], window[DECODER_INDEX_SINGLE]->sink,
759                                               NULL);                            
760              DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], window[DECODER_INDEX_DOUBLE]->sink,
761                                               NULL);
762                         decodeMode = DECODE_MODE_DUAL;
763                         setDecodeSwitch(DECODE_MODE_SINGLE);
764                         break;
765                 case DECODE_MODE_SINGLE:
766                         setControlMode (window[DECODER_INDEX_SINGLE],
767                                         CONTROL_MODE_PLAYING,
768                                         CONTROL_MODE_ACTIVE);
769                         setControlMode (window[DECODER_INDEX_DOUBLE],
770                                         CONTROL_MODE_PLAYING,
771                                         CONTROL_MODE_INACTIVE);
772             DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], window[DECODER_INDEX_SINGLE]->sink,
773                                               window[DECODER_INDEX_DOUBLE]->sink);
774             DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], NULL,
775                                             NULL);
776                         DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE],
777                                         filename[DECODER_INDEX_SINGLE],
778                                         SEEK_START);
779                         setDecodeSwitch(DECODE_MODE_DUAL);
780                         break;
781                 case DECODE_MODE_DUAL:
782                         setControlMode(window[DECODER_INDEX_SINGLE],
783                                         CONTROL_MODE_PLAYING,
784                                         CONTROL_MODE_ACTIVE);
785              DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], window[DECODER_INDEX_SINGLE]->sink,
786                                               NULL);
787              DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], window[DECODER_INDEX_DOUBLE]->sink,
788                                               NULL);
790                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
791                                         filename[DECODER_INDEX_SINGLE],
792                                         SEEK_START);
793                         setControlMode(window[DECODER_INDEX_DOUBLE],
794                                         CONTROL_MODE_PLAYING,
795                                         CONTROL_MODE_ACTIVE);
796                         DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
797                                         filename[DECODER_INDEX_DOUBLE],
798                                         SEEK_START);
799                         setDecodeSwitch(DECODE_MODE_SINGLE);
800                         break;
801         }
804 static GUIWindow *createWindow()
806         GUIWindow *ret  = NULL;
807         ret = g_malloc0(sizeof(GUIWindow));
808         if(NULL == ret){
809                 return ret;
810         }
811         DualDecode_builderCreate();
813         ret->window = DualDecode_getWidget("decodeWindowSingle");
814         if(NULL == ret->window){
815                 goto memCleanup;
816         }
817         ret->windowCloseSignal = g_signal_connect(G_OBJECT(ret->window),
818                         "delete-event",
819                         G_CALLBACK(cbWindowClosed),
820                         NULL);
822         GtkWidget *toolbar = DualDecode_getWidget("toolbarSingle");
823         if(NULL == toolbar){
824                 goto memCleanup;
825         }
826         ret->drawArea = DualDecode_getWidget("videoViewerSingle");
827         if(NULL == ret->drawArea){
828                 goto memCleanup;
829         }
831         ret->openButton = GTK_WIDGET(
832                         gtk_tool_button_new_from_stock(GTK_STOCK_OPEN));
833         if(NULL == ret->openButton){
834                 goto memCleanup;
835         }
836         ret->rewindButton = GTK_WIDGET(
837                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND));
838         if(NULL == ret->rewindButton){
839                 goto memCleanup;
840         }
841         ret->playButton = GTK_WIDGET(
842                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY));
843         if(NULL == ret->playButton){
844                 goto memCleanup;
845         }
846         ret->pauseButton = GTK_WIDGET(
847                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE));
848         if(NULL == ret->pauseButton){
849                 goto memCleanup;
850         }
851         ret->stopButton = GTK_WIDGET(
852                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP));
853         if(NULL == ret->stopButton){
854                 goto memCleanup;
855         }
856         ret->forwardButton = GTK_WIDGET(
857                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD));
858         if(NULL == ret->forwardButton){
859                 goto memCleanup;
860         }
861         ret->helpButton = GTK_WIDGET(
862                         gtk_tool_button_new_from_stock(GTK_STOCK_HELP));
863         if(NULL == ret->helpButton){
864                 goto memCleanup;
865         }
867         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
868                         GTK_TOOL_ITEM(ret->openButton),
869                         -1);
870         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
871                         gtk_separator_tool_item_new(),
872                         -1);
873         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
874                         GTK_TOOL_ITEM(ret->rewindButton),
875                         -1);
876         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
877                         GTK_TOOL_ITEM(ret->playButton),
878                         -1);
879         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
880                         GTK_TOOL_ITEM(ret->pauseButton),
881                         -1);
882         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
883                         GTK_TOOL_ITEM(ret->stopButton),
884                         -1);
885         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
886                         GTK_TOOL_ITEM(ret->forwardButton),
887                         -1);
888         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
889                         gtk_separator_tool_item_new(),
890                         -1);
891         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
892                         GTK_TOOL_ITEM(ret->helpButton),
893                         -1);
895         ret->openSignal = g_signal_connect(G_OBJECT(ret->openButton),
896                         "clicked",
897                         G_CALLBACK(cbOpenClicked),
898                         ret);
899         ret->stopSignal = g_signal_connect(G_OBJECT(ret->stopButton),
900                         "clicked",
901                         G_CALLBACK(cbStopClicked),
902                         ret);
903         ret->pauseSignal = g_signal_connect(G_OBJECT(ret->pauseButton),
904                         "clicked",
905                         G_CALLBACK(cbPauseClicked),
906                         ret);
907         ret->playSignal = g_signal_connect(G_OBJECT(ret->playButton),
908                         "clicked",
909                         G_CALLBACK(cbPlayClicked),
910                         ret);
911     ret->forwardSignal = g_signal_connect(G_OBJECT(ret->forwardButton),               
912             "clicked",                                                          
913             G_CALLBACK(cbForwardClicked),                                          
914             ret);
915     ret->rewindSignal = g_signal_connect(G_OBJECT(ret->rewindButton),               
916             "clicked",                                                          
917             G_CALLBACK(cbRewindClicked),                                          
918             ret);
920     ret->helpSignal = g_signal_connect(G_OBJECT(ret->helpButton),               
921             "clicked",                                                          
922             G_CALLBACK(cbHelpClicked),                                          
923             ret);   
926         ret->switchButton = DualDecode_getWidget("switchButtonSingle");
927         if(NULL == ret->switchButton){
928                 goto memCleanup;
929         }
931         ret->switchSignal = g_signal_connect (G_OBJECT (ret->switchButton),
932                         "clicked",
933                         G_CALLBACK (cbSwitchButtonClicked),
934                         ret);
936         ret->seekScale = DualDecode_getWidget("seekScaleSingle");
937         if(NULL == ret->seekScale){
938                 goto memCleanup;
939         }
941     ret->seekSignal = g_signal_connect (G_OBJECT (ret->seekScale),
942              "value_changed",
943              G_CALLBACK (cbSeekValueChanged),
944              ret);
945         
947         ret->statusLabel = DualDecode_getWidget("statusLabelSingle");
948         if(NULL == ret->statusLabel){
949                 goto memCleanup;
950         }
952         ret->timeLabel = DualDecode_getWidget("timeLabelSingle");
953         if(NULL == ret->timeLabel){
954                 goto memCleanup;
955         }
956     ret->activeFlag = FALSE;
958         goto last;
960         gtk_widget_destroy(ret->window);
961 memCleanup:
962         g_free(ret);
963 last:
964         DualDecode_builderClose();
965         return ret;
968 static GtkWidget *createLogWindow()
970         /*TODO: create help window*/
971         return gtk_window_new(GTK_WINDOW_TOPLEVEL);
974 static GtkWidget *createHelpWindow()
976     GtkWidget * helpWindow;
977     gint width;
978     gint height;
980     helpWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
981     gtk_window_set_title ( (GtkWindow *) helpWindow, "Help");
982     gtk_window_set_resizable ( (GtkWindow * )helpWindow, FALSE);
984     /*Set size same as display windows*/
985     gtk_widget_get_size_request (window[DECODER_INDEX_SINGLE]->window,
986                                  &width,
987                                  &height);  
988     gtk_widget_set_size_request (helpWindow, width, height);
989     /*Connect signal to close button handler*/
990     g_signal_connect(G_OBJECT (helpWindow), "delete-event", 
991       G_CALLBACK (cbHelpClosed), NULL);
992     g_print ("RETURNING FROM CREATE HELP\n");
993     return helpWindow;
997                                                          
998 /*static void logGUI(GtkWidget *logWindow, gchar *format, ...)
1000         //TODO: dummy now
1001 }*/
1002 static void setWindowSizeLocation()
1004         GdkScreen *screen               = NULL;
1005         gint screenWidth                = -1;
1006         gint screenHeight               = -1;
1007         gint windowWidth                = -1;
1008         gint windowHeight               = -1;
1010         screen = gdk_screen_get_default();
1011         screenWidth = gdk_screen_get_width(screen);
1012         screenHeight = gdk_screen_get_height(screen);
1013         windowWidth = screenWidth/SCREEN_WIDTH_FACTOR;
1014         windowHeight = screenHeight/SCREEN_HEIGHT_FACTOR;
1016         gtk_widget_set_size_request(window[DECODER_INDEX_SINGLE]->window,
1017                         windowWidth,windowHeight);
1018         gtk_widget_set_size_request(window[DECODER_INDEX_DOUBLE]->window,
1019                         windowWidth,windowHeight);
1020         gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_SINGLE]->window),
1021                         (screenWidth-2*windowWidth)/2,
1022                         0);
1023         gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_DOUBLE]->window),
1024                         (screenWidth-2*windowWidth)/2+windowWidth,
1025                         0);
1028 static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name)
1030     GstElement *sinkElement        = NULL;                                             
1031     XID xid                 = 0;                                                
1032     GdkDrawable *drawable   = NULL;                                             
1033                                                                                 
1034     /*make an xvimagesink element from factory*/                                
1035                                      
1036     sinkElement = gst_element_factory_make (sink,name);                        
1037     if (NULL == sinkElement){
1038         g_print ("%s sink cannot be created\n", sink);                                                           
1039         goto return_pos;                                                        
1040     }                                                                           
1041                                                                                 
1042     /*get the XID of the display window's drawable*/                            
1043     drawable = gtk_widget_get_window (GTK_WIDGET (window));                     
1044     if(FALSE == GDK_IS_DRAWABLE(drawable)){                                     
1045         /*TODO: A BUG HERE?*/                                                   
1046         g_object_unref(G_OBJECT(sinkElement));                                         
1047         sinkElement=NULL;                                                              
1048         goto return_pos;                                                        
1049     }                                                                           
1050     xid = gdk_x11_drawable_get_xid(drawable);                                   
1051                                                                                 
1052     /*link the gst sink element to the XID*/                                    
1053     gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sinkElement),xid);                    
1054                                                                                 
1055 return_pos:                                                                     
1056     return sinkElement;                                                                
1057 }   
1059 /******************************************************************************
1060  *      Exported Function Definition
1061  ******************************************************************************/
1063 /******************************************************************************
1064  *      See gui.h
1065  ******************************************************************************/
1066 void DualDecode_startApplication()
1069         window[DECODER_INDEX_SINGLE] = createWindow();
1070         g_assert(window[DECODER_INDEX_SINGLE] != NULL);
1072     /*window[DECODER_INDEX_SINGLE]->sink = createImageSinkFromWindow (
1073                                         window[DECODER_INDEX_SINGLE]->drawArea,
1074                                         "sink0");
1076     */
1077         window[DECODER_INDEX_DOUBLE] = createWindow();
1078         g_assert(window[DECODER_INDEX_DOUBLE] != NULL);
1080  /*  window[DECODER_INDEX_DOUBLE]->sink = createImageSinkFromWindow (            
1081                                         window[DECODER_INDEX_DOUBLE]->drawArea,          
1082                                         "sink1"); 
1083   */
1084         setWindowSizeLocation();
1086         helpWindow = createHelpWindow();
1087         g_assert (helpWindow != NULL);
1089         logWindow[DECODER_INDEX_SINGLE] = createLogWindow();
1090         g_assert (logWindow[DECODER_INDEX_SINGLE] != NULL);
1092         logWindow[DECODER_INDEX_DOUBLE] = createLogWindow();
1093         g_assert (logWindow[DECODER_INDEX_DOUBLE] != NULL);
1095         pipes[DECODER_INDEX_SINGLE] = DualDecode_createPipeline();
1096 /*      DualDecode_setLogFunction(pipes[DECODER_INDEX_SINGLE],
1097                         logGUI,
1098                         logWindow[DECODER_INDEX_SINGLE]);
1099 */
1100         pipes[DECODER_INDEX_DOUBLE] = DualDecode_createPipeline();
1101 /*      DualDecode_setLogFunction(pipes[DECODER_INDEX_DOUBLE],
1102                         logGUI,
1103                         logWindow[DECODER_INDEX_DOUBLE]);
1104 */
1105         setup();
1107         gtk_main();
1108     
1111 /******************************************************************************
1112  *      See gui.h
1113  ******************************************************************************/
1114 void DualDecode_exitApplication()
1116         gtk_widget_destroy(window[DECODER_INDEX_SINGLE]->window);
1117         gtk_widget_destroy(window[DECODER_INDEX_DOUBLE]->window);
1118         g_free(window[DECODER_INDEX_SINGLE]);
1119         g_free(window[DECODER_INDEX_DOUBLE]);
1120         gtk_widget_destroy(logWindow[DECODER_INDEX_SINGLE]);
1121         gtk_widget_destroy(logWindow[DECODER_INDEX_DOUBLE]);
1122         gtk_widget_destroy (helpWindow);
1124         /*TODO: destroy pipes here*/
1126     if (gtk_main_level())
1127         gtk_main_quit();
1128     exit(0);
1131 /******************************************************************************
1132  *      See gui.h
1133  ******************************************************************************/
1134 gboolean DualDecode_initGUI(gint *argc, char **argv[])
1136         return gtk_init_check(argc,argv);