Modified in acordance to coding guidelines.
[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         
59                       Static variables declaration
60  
61 *****************************************************************************/
62 static GUIWindow *window[]              = {NULL, NULL};
63 static Pipeline *pipes[]                = {NULL, NULL};
64 static GtkWidget *logWindow[]   = {NULL, NULL};
65 static GtkWidget *helpWindow    = NULL;
68 /******************************************************************************
69  
70                            Static functions declaration
72  ******************************************************************************/
73 static gint setAbsolutePathname (gchar *file, gchar **uri)  ;
74 static void setControlMode (GUIWindow *thisWindow,gint modeFlag,gint activeFlag);
75 static void setControlActive (GUIWindow *window, gboolean activeFlag);
76 static void setup();
77 static void setDecodeSwitch (gint decodeSwitch);
78 static GtkWidget *createLogWindow();
79 static GtkWidget *createHelpWindow();
80 static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name);
81 static void setWindowSizeLocation();
82 static GUIWindow *createWindow();
84 static gboolean cbOpenClicked (GtkWidget *widget, gpointer data);
85 static gboolean cbPlayClicked (GtkWidget *widget, gpointer data);
86 static gboolean cbPauseClicked (GtkWidget *widget, gpointer data);
87 static gboolean cbStopClicked (GtkWidget *widget, gpointer data);
88 static gboolean cbForwardClicked (GtkWidget *widget, gpointer data);
89 static gboolean cbRewindClicked (GtkWidget *widget, gpointer data);
90 static gboolean cbWindowClosed (GtkWidget *widget, gpointer data);
91 static gboolean cbHelpClicked (GtkWidget *widget, gpointer data);
92 static gboolean cbTimerInterval (gpointer data);
93 static gboolean cbSeekValueChanged (GtkWidget *widget, gpointer data);
94 static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data);
95 static gboolean cbHelpClosed (GtkWidget *widget, gpointer data);
96 //static void logGUI (GtkWidget *logWindow, gchar *format, ...); 
98 static gint setAbsolutePathname (gchar *file, gchar **uri)                             
99 {                                                                               
100     gchar *realPath = NULL;                                                     
101     gint ret        = ERR_SUCCESS;                                              
102                                                                                 
103     if(NULL == uri){                                                            
104         return ERR_INVALIDPARAM;                                                
105     }                                                                           
106                                                                                 
107     if(NULL == file){                                                           
108         /*A BUG Here*/                                                          
109         g_printerr("BUG: file: " __FILE__ " line: %d" "\n", __LINE__);          
110         return ERR_BUG;                                                         
111     }                                                                           
112                                                                                 
113     *uri = (gchar *) g_malloc (sizeof(gchar) * PATH_MAX_LEN);                   
114     realPath = realpath (file, realPath);                                       
115     if (NULL == realPath) {                                                     
116         /*TODO: a debug trace here*/                                            
117         g_printerr ("File %s not found\n", file);                               
118         ret = ERR_FILENOTFOUND;                                                 
119         goto destroy;                                                           
120     }                                                                           
121     g_snprintf(*uri,PATH_MAX_LEN,"file://%s",realPath);                         
122                                                                                 
123     goto last;                                                                  
124                                                                                 
125 destroy:                                                                        
126     g_free(*uri);                                                               
127     *uri=NULL;                                                                  
128 last:                                                                           
129     free (realPath);                                                            
130     return ret;                                                                 
131 }        
132 /******************************************************************************
133  
134                         Callback functions definition
136  ******************************************************************************/
138 /*Timer Interval Callback Function*/
139 static gboolean cbTimerInterval(gpointer data)
141         gdouble seekScaleValue = 0.0;
142         gchar *timeLabelText = TIME_LABEL_ORIGIN;
143         GUIWindow *thisWindow = (GUIWindow *)data;
144         gboolean ret = TRUE;
145     
146     //g_print ("IN timer");
147         if (DECODE_MODE_SINGLE == decodeMode){
148                 ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
149                                 &seekScaleValue,
150                                 &timeLabelText);
151         //g_print ("Seek Value %f", seekScaleValue);
153                 g_signal_handler_block (window[DECODER_INDEX_SINGLE]->seekScale,
154                                 window[DECODER_INDEX_SINGLE]->seekSignal);
155         gtk_range_set_value (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
156                                 seekScaleValue);
157                 gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
158                                 timeLabelText);
159                 g_signal_handler_unblock (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
160                                 window[DECODER_INDEX_SINGLE]->seekSignal);
162                 g_signal_handler_block (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
163                                 window[DECODER_INDEX_DOUBLE]->seekSignal);
164                 gtk_range_set_value(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
165                                 seekScaleValue);
166                 gtk_label_set_text(GTK_LABEL (window[DECODER_INDEX_DOUBLE]->timeLabel),
167                                 timeLabelText);
168                 g_signal_handler_unblock(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
169                                 window[DECODER_INDEX_DOUBLE]->seekSignal);
170         }else{
171                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
172                         ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
173                                         &seekScaleValue,
174                                         &timeLabelText);
175                         
176             g_signal_handler_block (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
177                                         window[DECODER_INDEX_SINGLE]->seekSignal);
178                         gtk_range_set_value (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
179                                         seekScaleValue);
180                         gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
181                                         timeLabelText);
182                         g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
183                                         window[DECODER_INDEX_SINGLE]->seekSignal);
184                 }else{
185                         ret = DualDecode_getMediaPosition (pipes[DECODER_INDEX_DOUBLE],
186                                         &seekScaleValue,
187                                         &timeLabelText);
189                         g_signal_handler_block (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
190                                         window[DECODER_INDEX_DOUBLE]->seekSignal);
191                         gtk_range_set_value (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
192                                         seekScaleValue);
193                         gtk_label_set_text (GTK_LABEL(window[DECODER_INDEX_DOUBLE]->timeLabel),
194                                         timeLabelText);
195                         g_signal_handler_unblock(GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
196                                         window[DECODER_INDEX_DOUBLE]->seekSignal);
197                 }
198         }
199         if(ret){
200                 g_free(timeLabelText);
201         }
202     return ret;
205 /*Seek Scale Changed Value Callback Function*/
206 static gboolean cbSeekValueChanged(GtkWidget *widget, gpointer data)
208     gboolean ret = TRUE;
209     GstFormat format = GST_FORMAT_TIME; 
210     gint64 duration = 0;
211     gint seekPoint = 0;
212     gdouble percent = gtk_range_get_value ((GtkRange *)widget);
213     g_print ("PERCENT %f\n", percent);
214     GUIWindow *thisWindow = (GUIWindow *)data; 
216     g_print ("IN SEEK VALUE CHANGED\n");
217     if (DECODE_MODE_SINGLE == decodeMode){
218                                                                                     
219         gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
220                                     &format,&duration);
221         seekPoint = (gint64) (duration * percent/ (gdouble)100);
222         g_print ("SEEK POINT %d\n", seekPoint);
223         ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);
224     }
225     else{                                                                      
226         if(window[DECODER_INDEX_SINGLE] == thisWindow){    
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_SINGLE], seekPoint);
231         } 
232         else {
233             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,
234                                        &format,&duration);              
235             seekPoint = (gint64) (duration * percent/ (gdouble)100);
236             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
237         }
238     }   
239     
240         return ret;
243 /*Open Button Clicked Callback Function*/
244 static gboolean cbOpenClicked(GtkWidget *widget, gpointer data)
246     gboolean ret = TRUE;
247     gchar *uri = NULL;
248     gchar *file = NULL;
249         GUIWindow *thisWindow = (GUIWindow *)data;
250         GtkWidget *fileChooser = gtk_file_chooser_dialog_new(
251                         "Open",
252                         GTK_WINDOW(thisWindow->window),
253                         GTK_FILE_CHOOSER_ACTION_OPEN,
254                         GTK_STOCK_OPEN,
255                         GTK_RESPONSE_OK,
256                         GTK_STOCK_CANCEL,
257                         GTK_RESPONSE_CANCEL,
258                         NULL);
259         gtk_window_set_modal(GTK_WINDOW(fileChooser),TRUE);
260         gtk_window_set_destroy_with_parent(GTK_WINDOW(fileChooser),TRUE);
261         gtk_widget_set_sensitive(thisWindow->window,FALSE);
262         
263         if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(fileChooser))){
264                 
265                 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser));
266                 
267         if (ERR_SUCCESS != setAbsolutePathname (file, &uri)){
268             ret = FALSE;
269             goto last;
270         }
271         //g_print ("FILE URI :%s", uri);
272                 if(DECODE_MODE_SINGLE == decodeMode){
273             filename[DECODER_INDEX_SINGLE] = uri;
274                         setControlMode(window[DECODER_INDEX_SINGLE],
275                                         CONTROL_MODE_PLAYING,
276                                         window[DECODER_INDEX_SINGLE]->activeFlag);
277                         setControlMode(window[DECODER_INDEX_DOUBLE],
278                                         CONTROL_MODE_PLAYING,
279                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
280                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
281                                         filename[DECODER_INDEX_SINGLE],
282                                         SEEK_START);
283                 }else{
284             filename[DECODER_INDEX_SINGLE] = uri;
285                         if(window[DECODER_INDEX_SINGLE] == thisWindow){
286                                 setControlMode(window[DECODER_INDEX_SINGLE],
287                                                 CONTROL_MODE_PLAYING,
288                                                 window[DECODER_INDEX_SINGLE]->activeFlag);
289                                 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
290                                                 filename[DECODER_INDEX_SINGLE],
291                                                 SEEK_START);
292                         }else{
293                 filename[DECODER_INDEX_DOUBLE] = uri;   
294                                 setControlMode(window[DECODER_INDEX_DOUBLE],
295                                                 CONTROL_MODE_PLAYING,
296                                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
297                                 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
298                                                 filename[DECODER_INDEX_DOUBLE],
299                                                 SEEK_START);
300                         }
301                 }
302         }
303         if (GTK_IS_WIDGET (fileChooser))
304                 gtk_widget_destroy (fileChooser);
306         if( GTK_IS_WIDGET (thisWindow->window))
307                 gtk_widget_set_sensitive (thisWindow->window,TRUE);
309 last:    return ret;
312 /*Play Button Clicked Callback Function*/
313 static gboolean cbPlayClicked(GtkWidget *widget, gpointer data)
315         gboolean ret = TRUE;
316     GUIWindow *thisWindow = (GUIWindow *)data;
318         if(DECODE_MODE_SINGLE == decodeMode){
319                 setControlMode(window[DECODER_INDEX_SINGLE],
320                                 CONTROL_MODE_PLAYING,
321                                 window[DECODER_INDEX_SINGLE]->activeFlag);
322                 setControlMode(window[DECODER_INDEX_DOUBLE],
323                                 CONTROL_MODE_PLAYING,
324                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
325                 if(GST_STATE_PAUSED == 
326                                 DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
327                         DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
328                 }else{
329                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
330                                         filename[DECODER_INDEX_SINGLE],
331                                         SEEK_START);
332              }
333         }else{
334                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
335                         setControlMode (window[DECODER_INDEX_SINGLE],
336                                         CONTROL_MODE_PLAYING,
337                                         window[DECODER_INDEX_SINGLE]->activeFlag);
338                         if (GST_STATE_PAUSED == 
339                                         DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
340                                 DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
341                         }else if (GST_STATE_READY == 
342                          DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
343                g_print ("\nPipeline state is READY\n");
344                DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
345                                                  window[DECODER_INDEX_SINGLE]->sink, 
346                                                  NULL); 
347                DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], filename[0],0);
348                //DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], 0);
349             }
351              else {
352                                   DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
353                                                 filename[DECODER_INDEX_SINGLE],
354                                                 SEEK_START);
355                         }
356                 }else{
357                         setControlMode(window[DECODER_INDEX_DOUBLE],
358                                         CONTROL_MODE_PLAYING,
359                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
360                         if(GST_STATE_PAUSED == 
361                                         DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
362                                 DualDecode_resumeMedia(pipes[DECODER_INDEX_DOUBLE]);
363                         }
364             else if (GST_STATE_READY ==                                        
365                          DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
366                DualDecode_resumeMedia (pipes[DECODER_INDEX_DOUBLE]);            
367                //DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], 0);         
368             }   
370             else{
371                                 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
372                                                 filename[DECODER_INDEX_DOUBLE],
373                                                 SEEK_START);
374                         }
375                 }
376         }
377     return ret;
380 /*Pause Button Clicked Callback Function*/
381 static gboolean cbPauseClicked(GtkWidget *widget, gpointer data)
383         gboolean ret = TRUE;
384     GUIWindow *thisWindow = (GUIWindow *)data;
386         if(DECODE_MODE_SINGLE == decodeMode){
387                 setControlMode(window[DECODER_INDEX_SINGLE],
388                                 CONTROL_MODE_PAUSED,
389                                 window[DECODER_INDEX_SINGLE]->activeFlag);
390                 setControlMode(window[DECODER_INDEX_DOUBLE],
391                                 CONTROL_MODE_PAUSED,
392                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
393                 DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
394         }else{
395                 if(window[DECODER_INDEX_SINGLE] == thisWindow){
396                         setControlMode(window[DECODER_INDEX_SINGLE],
397                                         CONTROL_MODE_PAUSED,
398                                         window[DECODER_INDEX_SINGLE]->activeFlag);
399                         DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
400                 }else{
401                         setControlMode(window[DECODER_INDEX_DOUBLE],
402                                         CONTROL_MODE_PAUSED,
403                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
404                         DualDecode_pauseMedia(pipes[DECODER_INDEX_DOUBLE]);
405                 }
406         }
407     return ret;
410 /*Stop Button Clicked Callback Function*/
411 static gboolean cbStopClicked(GtkWidget *widget, gpointer data)
413         gboolean ret = TRUE;
414     GUIWindow *thisWindow = (GUIWindow *)data;
415    
417         if (DECODE_MODE_SINGLE == decodeMode){
418                 setControlMode (window[DECODER_INDEX_SINGLE],
419                                 CONTROL_MODE_STOPPED,
420                                 window[DECODER_INDEX_SINGLE]->activeFlag);
421                 setControlMode (window[DECODER_INDEX_DOUBLE],
422                                 CONTROL_MODE_STOPPED,
423                                 window[DECODER_INDEX_DOUBLE]->activeFlag);
424                 DualDecode_stopMedia (pipes[DECODER_INDEX_SINGLE]);
425         }else{
426                 if (window[DECODER_INDEX_SINGLE] == thisWindow){
427                         setControlMode(window[DECODER_INDEX_SINGLE],
428                                         CONTROL_MODE_STOPPED,
429                                         window[DECODER_INDEX_SINGLE]->activeFlag);
430                         DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
431                 }else{
432                         setControlMode (window[DECODER_INDEX_DOUBLE],
433                                         CONTROL_MODE_STOPPED,
434                                         window[DECODER_INDEX_DOUBLE]->activeFlag);
435                         DualDecode_stopMedia (pipes[DECODER_INDEX_DOUBLE]);
436                 }
437         }
438     return ret;
440 static gboolean cbForwardClicked(GtkWidget *widget, gpointer data)                 
441 {                                                                               
442     gboolean ret = TRUE;                                                        
443     GstFormat format = GST_FORMAT_TIME;                                         
444     gint64 duration = 0;                                                        
445     gint64 seekPoint = 0;                                                         
446     GUIWindow *thisWindow = (GUIWindow *)data;               
447     gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));                   
448                                                                                 
449     g_print ("IN FORWARD CLICKED\n");                                        
450     if (DECODE_MODE_SINGLE == decodeMode){                                      
451                                                                                 
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         if(window[DECODER_INDEX_SINGLE] == thisWindow){                         
460             gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
461                                         &format, &duration);                     
462             seekPoint =  (duration * percent/ (gdouble)100) + FORWARD;
463             g_print ("SEEK POINT %d\n", seekPoint);            
464             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint); 
465         }                                                                       
466         else {                                                                  
467             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,       
468                                        &format,&duration);                      
469             seekPoint = (duration * percent/ (gdouble)100)+ FORWARD;            
470             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
471         }                                                                       
472     }                                                                           
473                                                                                 
474         return ret; 
475 }                                                                                
476 static gboolean cbRewindClicked(GtkWidget *widget, gpointer data)                 
478     gboolean ret = TRUE;                                                        
479     GstFormat format = GST_FORMAT_TIME;                                         
480     gint64 duration = 0;                                                        
481     gint64 seekPoint = 0;                                                       
482     GUIWindow *thisWindow = (GUIWindow *)data;                                  
483     gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));
484                                                                                 
485     g_print ("IN FORWARD CLICKED\n");                                           
486     if (DECODE_MODE_SINGLE == decodeMode){                                      
487                                                                                 
488         gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,          
489                                     &format,&duration);                         
490         seekPoint =  (duration * percent/ (gdouble)100) - REWIND;               
491         g_print ("SEEK POINT %d\n", seekPoint);
492         seekPoint = (seekPoint < 0) ? 0 : seekPoint;                                 
493         ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint);     
494     }                                                                           
495     else{                                                                       
496         if(window[DECODER_INDEX_SINGLE] == thisWindow){                         
497             gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
498                                         &format, &duration);                    
499             seekPoint =  (duration * percent/ (gdouble)100) - REWIND;          
500             g_print ("SEEK POINT %d\n", seekPoint);
501             seekPoint = (seekPoint < 0) ? 0 : seekPoint;                             
502             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_SINGLE], seekPoint); 
503         }                                                                       
504         else {                                                                  
505             gst_element_query_duration(pipes[DECODER_INDEX_SINGLE]->pipe,       
506                                        &format,&duration);                      
507             seekPoint = (duration * percent/ (gdouble)100) - REWIND;    
508             seekPoint = (seekPoint < 0) ? 0 : seekPoint;        
509             ret = DualDecode_seekMedia(pipes[DECODER_INDEX_DOUBLE], seekPoint); 
510         }                                                                       
511     }                                                                           
512                                                                                 
513         return ret;                                                                                  
514 }    
515 static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data)
517     gboolean ret = TRUE;
518     gboolean noFile = FALSE;
519     GUIWindow *thisWindow = (GUIWindow *) data;
520     gint otherWindowIndex = 0;
521     gint thisWindowIndex = 0;
523     /*No file is given yet to play. Application may be just started. */
524     if (NULL == filename[DECODER_INDEX_SINGLE])
525         noFile = TRUE;
527          
528         
530     if (thisWindow == window[DECODER_INDEX_SINGLE]){
531         thisWindowIndex = DECODER_INDEX_SINGLE;
532         otherWindowIndex = DECODER_INDEX_DOUBLE;
533     }
534     else {
535         otherWindowIndex = DECODER_INDEX_SINGLE;
536         thisWindowIndex = DECODER_INDEX_DOUBLE;
537     }
539     switch (decodeMode)
540     {
541       case DECODE_MODE_SINGLE :  
542           setControlMode (window[otherWindowIndex], window[otherWindowIndex]->modeFlag, 
543                           CONTROL_MODE_ACTIVE);
544           setControlMode (thisWindow, thisWindow->modeFlag,       
545                           CONTROL_MODE_ACTIVE);
547           if (FALSE == noFile) {
548           ret = DualDecode_singleToDual (pipes,
549                                          window[otherWindowIndex]->sink,
550                                          thisWindowIndex, otherWindowIndex, 
551                                          filename[DECODER_INDEX_SINGLE]);
552           }
553           decodeMode = DECODE_MODE_DUAL;
554           setDecodeSwitch(DECODE_MODE_SINGLE);
555           break;
557       case DECODE_MODE_DUAL :      
558           setControlMode (window[otherWindowIndex], thisWindow->modeFlag, 
559                           CONTROL_MODE_INACTIVE);  
561           if (FALSE == noFile) {
562           ret = DualDecode_dualToSingle (pipes,
563                                          window[otherWindowIndex]->sink,        
564                                          thisWindowIndex, otherWindowIndex);
565            }
566            decodeMode = DECODE_MODE_SINGLE; 
567            setDecodeSwitch(DECODE_MODE_DUAL);  
568           
569           break;
570     } 
573     return ret;
575 /*Window Close Callback Function*/
576 static gboolean cbWindowClosed(GtkWidget *widget, gpointer data){
577         DualDecode_exitApplication();
578     return TRUE;
581 static gboolean cbHelpClicked (GtkWidget *widget, gpointer data){
582     g_print ("HELP BUTTON CLICKED\n");
583     gtk_widget_show (helpWindow);
584     return TRUE;
587 static gboolean cbHelpClosed (GtkWidget *widget, gpointer data){
588     g_print ("IN HELP CLOSED\n");
589     gtk_widget_hide (helpWindow);
590     return TRUE;
592 /******************************************************************************
593  
594                         Static utility functions definition
596  ******************************************************************************/
597 static void setControlActive(GUIWindow *window, gboolean activeFlag)
599         gtk_widget_set_sensitive(window->playButton,activeFlag);
600         gtk_widget_set_sensitive(window->pauseButton,activeFlag);
601         gtk_widget_set_sensitive(window->stopButton,activeFlag);
602         gtk_widget_set_sensitive(window->rewindButton,activeFlag);
603         gtk_widget_set_sensitive(window->forwardButton,activeFlag);
604         gtk_widget_set_sensitive(window->openButton,activeFlag);
605         gtk_widget_set_sensitive(window->seekScale,activeFlag);
606     gtk_widget_set_sensitive (window->switchButton, activeFlag);
607     
610 static void setControlMode(GUIWindow *thisWindow,
611                 gint modeFlag,
612                 gint activeFlag)
614         setControlActive(thisWindow, activeFlag);
615         if(activeFlag){
616                 switch(modeFlag){
617                         case CONTROL_MODE_NO_FILE:
618                                 gtk_widget_set_sensitive(thisWindow->playButton,FALSE);
619                                 gtk_widget_set_sensitive(thisWindow->pauseButton,FALSE);
621                                 gtk_widget_set_sensitive(thisWindow->stopButton,FALSE);
622                                 gtk_widget_set_sensitive(thisWindow->rewindButton,FALSE);
623                                 gtk_widget_set_sensitive(thisWindow->forwardButton,FALSE);
624                                 gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
626                                 break;
627                         case CONTROL_MODE_PLAYING:
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,TRUE);
636                                 break;
637                         case CONTROL_MODE_STOPPED:
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,FALSE);
646                                 break;
647                         case CONTROL_MODE_PAUSED:
648                                 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
649                                 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
651                                 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
652                                 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
653                                 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
654                                 gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
656                                 break;
657                 }
658         }
659         switch(modeFlag){
660                 case CONTROL_MODE_NO_FILE:
661                         gtk_widget_show(thisWindow->playButton);
662                         gtk_widget_hide(thisWindow->pauseButton);
664                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
665                                         LABEL_TEXT_NO_FILE);
666                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
667                                         TIME_LABEL_ORIGIN);
668                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
669                                 g_source_remove(thisWindow->timerSignal);
670                                 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
671                         }
672                         break;
673                 case CONTROL_MODE_PLAYING:
674                         gtk_widget_show(thisWindow->pauseButton);
675                         gtk_widget_hide(thisWindow->playButton);
677                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
678                                         LABEL_TEXT_PLAYING);
679                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
680                                         TIME_LABEL_ORIGIN);
682                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
683                                 g_source_remove(thisWindow->timerSignal);
684             }
685                         thisWindow->timerSignal = g_timeout_add(TIMER_INTERVAL,
686                                                 cbTimerInterval,
687                                                 thisWindow); 
688                         
689                         break;
690                 case CONTROL_MODE_STOPPED:
691                         gtk_widget_show(thisWindow->playButton);
692                         gtk_widget_hide(thisWindow->pauseButton);
694                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
695                                         LABEL_TEXT_STOPPED);
696                         gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
697                                         TIME_LABEL_ORIGIN);
699                         if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
700                                 g_source_remove(thisWindow->timerSignal);
701                                 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
702                         }
703                         break;
704                 case CONTROL_MODE_PAUSED:
705                         gtk_widget_show(thisWindow->playButton);
706                         gtk_widget_hide(thisWindow->pauseButton);
708                         gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
709                                         LABEL_TEXT_PAUSED);
710                         break;
712         }
713         thisWindow->modeFlag = modeFlag;
714         thisWindow->activeFlag = activeFlag;
717 static void setDecodeSwitch(gint decodeSwitch)
719         switch (decodeSwitch){
720                 case DECODE_MODE_SINGLE:
721                         gtk_button_set_label(
722                                         GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
723                                         SWITCH_TEXT_SINGLE);
724                         gtk_button_set_label(
725                                         GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
726                                         SWITCH_TEXT_SINGLE);
727                         break;
728                 case DECODE_MODE_DUAL:
729                         gtk_button_set_label(
730                                         GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
731                                         SWITCH_TEXT_DUAL);
732                         gtk_button_set_label(
733                                         GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
734                                         SWITCH_TEXT_DUAL);
735         }
738 static void setup()
741     g_print ("SINK TO BE USED %s\n", sink);
742         gtk_widget_show_all (window[DECODER_INDEX_SINGLE]->window);
743         gtk_widget_show_all (window[DECODER_INDEX_DOUBLE]->window);
745     window[DECODER_INDEX_SINGLE]->sink = createImageSinkFromWindow (            
746                                         window[DECODER_INDEX_SINGLE]->drawArea, 
747                                         "windowsink0"); 
749     window[DECODER_INDEX_DOUBLE]->sink = createImageSinkFromWindow (           
750                                         window[DECODER_INDEX_DOUBLE]->drawArea, 
751                                         "windowsink1"); 
753     /*If any of the sinks is NULL the application exits*/
755     if (NULL == window[DECODER_INDEX_SINGLE]->sink || 
756         NULL == window[DECODER_INDEX_DOUBLE]->sink) {
757             DualDecode_exitApplication();
758     
759     }
760         switch(decodeMode){
761                 case DECODE_MODE_NONE:
762                         setControlMode(window[DECODER_INDEX_SINGLE],
763                                         CONTROL_MODE_NO_FILE,
764                                         CONTROL_MODE_ACTIVE);
765                         setControlMode(window[DECODER_INDEX_DOUBLE],
766                                         CONTROL_MODE_NO_FILE,
767                                         CONTROL_MODE_ACTIVE);
768              DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
769                                          window[DECODER_INDEX_SINGLE]->sink,
770                                               NULL);                            
771              DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], 
772                                          window[DECODER_INDEX_DOUBLE]->sink,
773                                               NULL);
774                         decodeMode = DECODE_MODE_DUAL;
775                         setDecodeSwitch(DECODE_MODE_SINGLE);
776                         break;
777                 case DECODE_MODE_SINGLE:
778                         setControlMode (window[DECODER_INDEX_SINGLE],
779                                         CONTROL_MODE_PLAYING,
780                                         CONTROL_MODE_ACTIVE);
781                         setControlMode (window[DECODER_INDEX_DOUBLE],
782                                         CONTROL_MODE_PLAYING,
783                                         CONTROL_MODE_INACTIVE);
784             DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
785                                         window[DECODER_INDEX_SINGLE]->sink,
786                                         window[DECODER_INDEX_DOUBLE]->sink);
787             DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], NULL,
788                                             NULL);
789                         DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE],
790                                         filename[DECODER_INDEX_SINGLE],
791                                         SEEK_START);
792                         setDecodeSwitch(DECODE_MODE_DUAL);
793                         break;
794                 case DECODE_MODE_DUAL:
795                         setControlMode(window[DECODER_INDEX_SINGLE],
796                                         CONTROL_MODE_PLAYING,
797                                         CONTROL_MODE_ACTIVE);
798              DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
799                                          window[DECODER_INDEX_SINGLE]->sink,
800                                               NULL);
801              DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], 
802                                          window[DECODER_INDEX_DOUBLE]->sink,
803                                               NULL);
805                         DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
806                                         filename[DECODER_INDEX_SINGLE],
807                                         SEEK_START);
808                         setControlMode(window[DECODER_INDEX_DOUBLE],
809                                         CONTROL_MODE_PLAYING,
810                                         CONTROL_MODE_ACTIVE);
811                         DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
812                                         filename[DECODER_INDEX_DOUBLE],
813                                         SEEK_START);
814                         setDecodeSwitch(DECODE_MODE_SINGLE);
815                         break;
816         }
819 static GUIWindow *createWindow()
821         GUIWindow *ret  = NULL;
822         ret = g_malloc0(sizeof(GUIWindow));
823         if(NULL == ret){
824                 return ret;
825         }
826         DualDecode_builderCreate();
828         ret->window = DualDecode_getWidget("decodeWindowSingle");
829         if(NULL == ret->window){
830                 goto memCleanup;
831         }
832         ret->windowCloseSignal = g_signal_connect(G_OBJECT(ret->window),
833                         "delete-event",
834                         G_CALLBACK(cbWindowClosed),
835                         NULL);
837         GtkWidget *toolbar = DualDecode_getWidget("toolbarSingle");
838         if(NULL == toolbar){
839                 goto memCleanup;
840         }
841         ret->drawArea = DualDecode_getWidget("videoViewerSingle");
842         if(NULL == ret->drawArea){
843                 goto memCleanup;
844         }
846         ret->openButton = GTK_WIDGET(
847                         gtk_tool_button_new_from_stock(GTK_STOCK_OPEN));
848         if(NULL == ret->openButton){
849                 goto memCleanup;
850         }
851         ret->rewindButton = GTK_WIDGET(
852                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND));
853         if(NULL == ret->rewindButton){
854                 goto memCleanup;
855         }
856         ret->playButton = GTK_WIDGET(
857                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY));
858         if(NULL == ret->playButton){
859                 goto memCleanup;
860         }
861         ret->pauseButton = GTK_WIDGET(
862                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE));
863         if(NULL == ret->pauseButton){
864                 goto memCleanup;
865         }
866         ret->stopButton = GTK_WIDGET(
867                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP));
868         if(NULL == ret->stopButton){
869                 goto memCleanup;
870         }
871         ret->forwardButton = GTK_WIDGET(
872                         gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD));
873         if(NULL == ret->forwardButton){
874                 goto memCleanup;
875         }
876         ret->helpButton = GTK_WIDGET(
877                         gtk_tool_button_new_from_stock(GTK_STOCK_HELP));
878         if(NULL == ret->helpButton){
879                 goto memCleanup;
880         }
882         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
883                         GTK_TOOL_ITEM(ret->openButton),
884                         -1);
885         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
886                         gtk_separator_tool_item_new(),
887                         -1);
888         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
889                         GTK_TOOL_ITEM(ret->rewindButton),
890                         -1);
891         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
892                         GTK_TOOL_ITEM(ret->playButton),
893                         -1);
894         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
895                         GTK_TOOL_ITEM(ret->pauseButton),
896                         -1);
897         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
898                         GTK_TOOL_ITEM(ret->stopButton),
899                         -1);
900         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
901                         GTK_TOOL_ITEM(ret->forwardButton),
902                         -1);
903         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
904                         gtk_separator_tool_item_new(),
905                         -1);
906         gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
907                         GTK_TOOL_ITEM(ret->helpButton),
908                         -1);
910         ret->openSignal = g_signal_connect(G_OBJECT(ret->openButton),
911                         "clicked",
912                         G_CALLBACK(cbOpenClicked),
913                         ret);
914         ret->stopSignal = g_signal_connect(G_OBJECT(ret->stopButton),
915                         "clicked",
916                         G_CALLBACK(cbStopClicked),
917                         ret);
918         ret->pauseSignal = g_signal_connect(G_OBJECT(ret->pauseButton),
919                         "clicked",
920                         G_CALLBACK(cbPauseClicked),
921                         ret);
922         ret->playSignal = g_signal_connect(G_OBJECT(ret->playButton),
923                         "clicked",
924                         G_CALLBACK(cbPlayClicked),
925                         ret);
926     ret->forwardSignal = g_signal_connect(G_OBJECT(ret->forwardButton),               
927             "clicked",                                                          
928             G_CALLBACK(cbForwardClicked),                                          
929             ret);
930     ret->rewindSignal = g_signal_connect(G_OBJECT(ret->rewindButton),               
931             "clicked",                                                          
932             G_CALLBACK(cbRewindClicked),                                          
933             ret);
935     ret->helpSignal = g_signal_connect(G_OBJECT(ret->helpButton),               
936             "clicked",                                                          
937             G_CALLBACK(cbHelpClicked),                                          
938             ret);   
941         ret->switchButton = DualDecode_getWidget("switchButtonSingle");
942         if(NULL == ret->switchButton){
943                 goto memCleanup;
944         }
946         ret->switchSignal = g_signal_connect (G_OBJECT (ret->switchButton),
947                         "clicked",
948                         G_CALLBACK (cbSwitchButtonClicked),
949                         ret);
951         ret->seekScale = DualDecode_getWidget("seekScaleSingle");
952         if(NULL == ret->seekScale){
953                 goto memCleanup;
954         }
956     ret->seekSignal = g_signal_connect (G_OBJECT (ret->seekScale),
957              "value_changed",
958              G_CALLBACK (cbSeekValueChanged),
959              ret);
960         
962         ret->statusLabel = DualDecode_getWidget("statusLabelSingle");
963         if(NULL == ret->statusLabel){
964                 goto memCleanup;
965         }
967         ret->timeLabel = DualDecode_getWidget("timeLabelSingle");
968         if(NULL == ret->timeLabel){
969                 goto memCleanup;
970         }
971     ret->activeFlag = FALSE;
973         goto last;
975         gtk_widget_destroy(ret->window);
976 memCleanup:
977         g_free(ret);
978 last:
979         DualDecode_builderClose();
980         return ret;
983 static GtkWidget *createLogWindow()
985         /*TODO: create help window*/
986         return gtk_window_new(GTK_WINDOW_TOPLEVEL);
989 static GtkWidget *createHelpWindow()
991     GtkWidget * helpWindow;
992     gint width;
993     gint height;
995     helpWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
996     gtk_window_set_title ( (GtkWindow *) helpWindow, "Help");
997     gtk_window_set_resizable ( (GtkWindow * )helpWindow, FALSE);
999     /*Set size same as display windows*/
1000     gtk_widget_get_size_request (window[DECODER_INDEX_SINGLE]->window,
1001                                  &width,
1002                                  &height);  
1003     gtk_widget_set_size_request (helpWindow, width, height);
1004     /*Connect signal to close button handler*/
1005     g_signal_connect(G_OBJECT (helpWindow), "delete-event", 
1006       G_CALLBACK (cbHelpClosed), NULL);
1007     g_print ("RETURNING FROM CREATE HELP\n");
1008     return helpWindow;
1012                                                          
1013 /*static void logGUI(GtkWidget *logWindow, gchar *format, ...)
1015         //TODO: dummy now
1016 }*/
1017 static void setWindowSizeLocation()
1019         GdkScreen *screen               = NULL;
1020         gint screenWidth                = -1;
1021         gint screenHeight               = -1;
1022         gint windowWidth                = -1;
1023         gint windowHeight               = -1;
1025         screen = gdk_screen_get_default();
1026         screenWidth = gdk_screen_get_width(screen);
1027         screenHeight = gdk_screen_get_height(screen);
1028         windowWidth = screenWidth/SCREEN_WIDTH_FACTOR;
1029         windowHeight = screenHeight/SCREEN_HEIGHT_FACTOR;
1031         gtk_widget_set_size_request(window[DECODER_INDEX_SINGLE]->window,
1032                         windowWidth,windowHeight);
1033         gtk_widget_set_size_request(window[DECODER_INDEX_DOUBLE]->window,
1034                         windowWidth,windowHeight);
1035         gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_SINGLE]->window),
1036                         (screenWidth-2*windowWidth)/2,
1037                         0);
1038         gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_DOUBLE]->window),
1039                         (screenWidth-2*windowWidth)/2+windowWidth,
1040                         0);
1043 static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name)
1045     GstElement *sinkElement        = NULL;                                             
1046     XID xid                 = 0;                                                
1047     GdkDrawable *drawable   = NULL;                                             
1048                                                                                 
1049     /*make an xvimagesink element from factory*/                                
1050                                      
1051     sinkElement = gst_element_factory_make (sink,name);                        
1052     if (NULL == sinkElement){
1053         g_print ("%s sink cannot be created\n", sink);                                                           
1054         goto return_pos;                                                        
1055     }                                                                           
1056                                                                                 
1057     /*get the XID of the display window's drawable*/                            
1058     drawable = gtk_widget_get_window (GTK_WIDGET (window));                     
1059     if(FALSE == GDK_IS_DRAWABLE(drawable)){                                     
1060         /*TODO: A BUG HERE?*/                                                   
1061         g_object_unref (G_OBJECT (sinkElement));                                         
1062         sinkElement=NULL;                                                              
1063         goto return_pos;                                                        
1064     }                                                                           
1065     xid = gdk_x11_drawable_get_xid(drawable);                                   
1066                                                                                 
1067     /*link the gst sink element to the XID*/                                    
1068     gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sinkElement),xid);                    
1069                                                                                 
1070 return_pos:                                                                     
1071     return sinkElement;                                                                
1072 }   
1074 /******************************************************************************
1075  *      Exported Function Definition
1076  ******************************************************************************/
1078 /******************************************************************************
1079  *      See gui.h
1080  ******************************************************************************/
1081 void DualDecode_startApplication()
1084         window[DECODER_INDEX_SINGLE] = createWindow();
1085         g_assert(window[DECODER_INDEX_SINGLE] != NULL);
1087     /*window[DECODER_INDEX_SINGLE]->sink = createImageSinkFromWindow (
1088                                         window[DECODER_INDEX_SINGLE]->drawArea,
1089                                         "sink0");
1091     */
1092         window[DECODER_INDEX_DOUBLE] = createWindow();
1093         g_assert(window[DECODER_INDEX_DOUBLE] != NULL);
1095  /*  window[DECODER_INDEX_DOUBLE]->sink = createImageSinkFromWindow (            
1096                                         window[DECODER_INDEX_DOUBLE]->drawArea,          
1097                                         "sink1"); 
1098   */
1099         setWindowSizeLocation();
1101         helpWindow = createHelpWindow();
1102         g_assert (helpWindow != NULL);
1104         logWindow[DECODER_INDEX_SINGLE] = createLogWindow();
1105         g_assert (logWindow[DECODER_INDEX_SINGLE] != NULL);
1107         logWindow[DECODER_INDEX_DOUBLE] = createLogWindow();
1108         g_assert (logWindow[DECODER_INDEX_DOUBLE] != NULL);
1110         pipes[DECODER_INDEX_SINGLE] = DualDecode_createPipeline();
1111 /*      DualDecode_setLogFunction(pipes[DECODER_INDEX_SINGLE],
1112                         logGUI,
1113                         logWindow[DECODER_INDEX_SINGLE]);
1114 */
1115         pipes[DECODER_INDEX_DOUBLE] = DualDecode_createPipeline();
1116 /*      DualDecode_setLogFunction(pipes[DECODER_INDEX_DOUBLE],
1117                         logGUI,
1118                         logWindow[DECODER_INDEX_DOUBLE]);
1119 */
1120         setup();
1122         gtk_main();
1123     
1126 /******************************************************************************
1127  *      See gui.h
1128  ******************************************************************************/
1129 void DualDecode_exitApplication()
1131         gtk_widget_destroy(window[DECODER_INDEX_SINGLE]->window);
1132         gtk_widget_destroy(window[DECODER_INDEX_DOUBLE]->window);
1133         g_free(window[DECODER_INDEX_SINGLE]);
1134         g_free(window[DECODER_INDEX_DOUBLE]);
1135         gtk_widget_destroy(logWindow[DECODER_INDEX_SINGLE]);
1136         gtk_widget_destroy(logWindow[DECODER_INDEX_DOUBLE]);
1137         gtk_widget_destroy (helpWindow);
1139         /*TODO: destroy pipes here*/
1141     if (gtk_main_level())
1142         gtk_main_quit();
1143     exit(0);
1146 /******************************************************************************
1147  *      See gui.h
1148  ******************************************************************************/
1149 gboolean DualDecode_initGUI(gint *argc, char **argv[])
1151         return gtk_init_check(argc,argv);