]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/dual-decode.git/blobdiff - src/gui.c
Modified in accordance to coding guidelines for header and C files.
[glsdk/dual-decode.git] / src / gui.c
old mode 100755 (executable)
new mode 100644 (file)
index 63de8e5..4c979eb
--- a/src/gui.c
+++ b/src/gui.c
@@ -1,43 +1,44 @@
-/*
- *  Copyright (c) 2010-2011, Texas Instruments Incorporated
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions
- *  are met:
- *
- *  *  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  *  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- *  *  Neither the name of Texas Instruments Incorporated nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  Contact information for paper mail:
- *  Texas Instruments
- *  Post Office Box 655303
- *  Dallas, Texas 75265
- *  Contact information:
- *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm
- *  ?DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+/*                                                                              
+ *  Copyright (c) 2012-2013, Texas Instruments Incorporated                     
+ *                                                                              
+ *  Redistribution and use in source and binary forms, with or without          
+ *  modification, are permitted provided that the following conditions          
+ *  are met:                                                                    
+ *                                                                              
+ *  *  Redistributions of source code must retain the above copyright           
+ *   notice, this list of conditions and the following disclaimer.              
+ *                                                                              
+ *  *  Redistributions in binary form must reproduce the above copyright        
+ *   notice, this list of conditions and the following disclaimer in the        
+ *   documentation and/or other materials provided with the distribution.       
+ *                                                                              
+ *  *  Neither the name of Texas Instruments Incorporated nor the names of      
+ *   its contributors may be used to endorse or promote products derived        
+ *   from this software without specific prior written permission.              
+ *                                                                              
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,       
+ *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,       
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,         
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,    
+ *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR     
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,              
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                          
+ *                                                                              
+ *  Contact information for paper mail:                                         
+ *  Texas Instruments                                                           
+ *  Post Office Box 655303                                                      
+ *  Dallas, Texas 75265                                                         
+ *  Contact information:                                                        
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact                             
  *  ============================================================================
- *
- */
+ *                                                                              
+ */                                                                             
+
 
 /**
  * @file               gui.c
  * @brief              Defines the functions exported by the GUI.
  *                             Also, defines the static functions and the callback funtions
  */
-
+#include <string.h>
+#include <linux/limits.h>
 #include <gtk/gtk.h>
-#include <gst/gst.h>
+#include <gdk/gdkx.h>                                                           
+#include <gst/interfaces/xoverlay.h>  
 
 #include <gui.h>
 #include <common.h>
 #include <gst-controller.h>
 
+/******************************************************************************
+       
+                      Static variables declaration
+*****************************************************************************/
 static GUIWindow *window[]             = {NULL, NULL};
 static Pipeline *pipes[]               = {NULL, NULL};
-static GtkWidget *helpWindow   = NULL;
 static GtkWidget *logWindow[]  = {NULL, NULL};
+static GtkWidget *helpWindow   = NULL;
 
 
-static void setControlActive(GUIWindow *window, gboolean activeFlag)
+/******************************************************************************
+                          Static functions declaration
+
+ ******************************************************************************/
+static gint setAbsolutePathname (gchar *file, gchar **uri)  ;
+static void setControlMode (GUIWindow *thisWindow,gint modeFlag,gint activeFlag);
+static void setControlActive (GUIWindow *window, gboolean activeFlag);
+static void setup();
+static void setDecodeSwitch (gint decodeSwitch);
+static GtkWidget *createLogWindow ();
+static GtkWidget *createHelpWindow ();
+static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name);
+static void setWindowSizeLocation ();
+static GUIWindow *createWindow ();
+
+static gboolean cbOpenClicked (GtkWidget *widget, gpointer data);
+static gboolean cbPlayClicked (GtkWidget *widget, gpointer data);
+static gboolean cbPauseClicked (GtkWidget *widget, gpointer data);
+static gboolean cbStopClicked (GtkWidget *widget, gpointer data);
+static gboolean cbForwardClicked (GtkWidget *widget, gpointer data);
+static gboolean cbRewindClicked (GtkWidget *widget, gpointer data);
+static gboolean cbWindowClosed (GtkWidget *widget, gpointer data);
+static gboolean cbHelpClicked (GtkWidget *widget, gpointer data);
+static gboolean cbTimerInterval (gpointer data);
+static gboolean cbSeekValueChanged (GtkWidget *widget, gpointer data);
+static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data);
+static gboolean cbHelpClosed (GtkWidget *widget, gpointer data);
+
+static gint setAbsolutePathname (gchar *file, gchar **uri)                             
+{                                                                               
+    gchar *realPath = NULL;                                                     
+    gint ret        = ERR_SUCCESS;                                              
+                                                                                
+    if (NULL == uri){                                                            
+        return ERR_INVALIDPARAM;                                                
+    }                                                                           
+                                                                                
+    if (NULL == file){                                                           
+        /*A BUG Here*/                                                          
+        g_printerr ("BUG: file: " __FILE__ " line: %d" "\n", __LINE__);          
+        return ERR_BUG;                                                         
+    }                                                                           
+                                                                                
+    *uri = (gchar *) g_malloc (sizeof(gchar) * PATH_MAX_LEN);                   
+    realPath = realpath (file, realPath);                                       
+    if (NULL == realPath) {                                                     
+        /*TODO: a debug trace here*/                                            
+        g_printerr ("File %s not found\n", file);                               
+        ret = ERR_FILENOTFOUND;                                                 
+        goto destroy;                                                           
+    }                                                                           
+    g_snprintf (*uri,PATH_MAX_LEN,"file://%s",realPath);                         
+                                                                                
+    goto last;                                                                  
+                                                                                
+destroy:                                                                        
+    g_free(*uri);                                                               
+    *uri=NULL;                                                                  
+last:                                                                           
+    free (realPath);                                                            
+    return ret;                                                                 
+}        
+/******************************************************************************
+                       Callback functions definition
+
+ ******************************************************************************/
+
+/*Timer Interval Callback Function*/
+static gboolean cbTimerInterval(gpointer data)
+{
+       gdouble seekScaleValue = 0.0;
+       gchar *timeLabelText = TIME_LABEL_ORIGIN;
+       GUIWindow *thisWindow = (GUIWindow *)data;
+       gboolean ret = TRUE;
+    
+       if (DECODE_MODE_SINGLE == decodeMode) {
+               ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
+                                                         &seekScaleValue, &timeLabelText);
+
+               g_signal_handler_block (window[DECODER_INDEX_SINGLE]->seekScale,
+                               window[DECODER_INDEX_SINGLE]->seekSignal);
+        gtk_range_set_value (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
+                               seekScaleValue);
+               gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
+                               timeLabelText);
+               g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
+                                                 window[DECODER_INDEX_SINGLE]->seekSignal);
+
+               g_signal_handler_block (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                                window[DECODER_INDEX_DOUBLE]->seekSignal);
+               gtk_range_set_value (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                           seekScaleValue);
+               gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_DOUBLE]->timeLabel),
+                                          timeLabelText);
+               g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                                 window[DECODER_INDEX_DOUBLE]->seekSignal);
+       }
+    else {
+               if (window[DECODER_INDEX_SINGLE] == thisWindow){
+                       ret = DualDecode_getMediaPosition (pipes[DECODER_INDEX_SINGLE],
+                                                                  &seekScaleValue, &timeLabelText);
+                       
+            g_signal_handler_block (GTK_RANGE(window[DECODER_INDEX_SINGLE]->seekScale),
+                                                       window[DECODER_INDEX_SINGLE]->seekSignal);
+                       gtk_range_set_value (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
+                                                    seekScaleValue);
+                       gtk_label_set_text (GTK_LABEL (window[DECODER_INDEX_SINGLE]->timeLabel),
+                                                   timeLabelText);
+                       g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_SINGLE]->seekScale),
+                                                         window[DECODER_INDEX_SINGLE]->seekSignal);
+               }
+        else {
+                       ret = DualDecode_getMediaPosition (pipes[DECODER_INDEX_DOUBLE],
+                                                                  &seekScaleValue, &timeLabelText);
+
+                       g_signal_handler_block (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                                       window[DECODER_INDEX_DOUBLE]->seekSignal);
+                       gtk_range_set_value (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                                    seekScaleValue);
+                       gtk_label_set_text (GTK_LABEL(window[DECODER_INDEX_DOUBLE]->timeLabel),
+                                                   timeLabelText);
+                       g_signal_handler_unblock (GTK_RANGE (window[DECODER_INDEX_DOUBLE]->seekScale),
+                                                         window[DECODER_INDEX_DOUBLE]->seekSignal);
+               }
+       }
+       if (ret) {
+               g_free (timeLabelText);
+       }
+    return ret;
+}
+
+/*Seek Scale Changed Value Callback Function*/
+static gboolean cbSeekValueChanged (GtkWidget *widget, gpointer data)
 {
-       gtk_widget_set_sensitive(window->playButton,activeFlag);
-       gtk_widget_set_sensitive(window->pauseButton,activeFlag);
-       gtk_widget_set_sensitive(window->stopButton,activeFlag);
-       gtk_widget_set_sensitive(window->rewindButton,activeFlag);
-       gtk_widget_set_sensitive(window->forwardButton,activeFlag);
-       gtk_widget_set_sensitive(window->openButton,activeFlag);
-       gtk_widget_set_sensitive(window->seekScale,activeFlag);
+    gboolean ret = TRUE;
+    GstFormat format = GST_FORMAT_TIME; 
+    gint64 duration = 0;
+    gint seekPoint = 0;
+    gdouble percent = gtk_range_get_value ((GtkRange *)widget);
+    g_print ("PERCENT %f\n", percent);
+    GUIWindow *thisWindow = (GUIWindow *)data; 
+
+    g_print ("IN SEEK VALUE CHANGED\n");
+    if (DECODE_MODE_SINGLE == decodeMode) {
+                                                                                    
+        gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
+                                    &format,&duration);
+        seekPoint = (gint64) (duration * percent/ (gdouble)100);
+        g_print ("SEEK POINT %d\n", seekPoint);
+        ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint);
+    }
+    else {                                                                      
+        if (window[DECODER_INDEX_SINGLE] == thisWindow){    
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
+                                        &format,&duration);              
+            seekPoint = (gint64) (duration * percent/ (gdouble)100);
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint);
+    } 
+        else {
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,
+                                        &format,&duration);              
+            seekPoint = (gint64) (duration * percent/ (gdouble)100);
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_DOUBLE], seekPoint); 
+        }
+    }   
+    
+        return ret;
 }
 
-static void setControlMode(GUIWindow *thisWindow,
-               gint modeFlag,
-               gint activeFlag)
+/*Open Button Clicked Callback Function*/
+static gboolean cbOpenClicked (GtkWidget *widget, gpointer data)
 {
-       setControlActive(thisWindow, activeFlag);
-       if(activeFlag){
-               switch(modeFlag){
-                       case CONTROL_MODE_NO_FILE:
-                               gtk_widget_set_sensitive(thisWindow->playButton,FALSE);
-                               gtk_widget_set_sensitive(thisWindow->pauseButton,FALSE);
-
-                               gtk_widget_set_sensitive(thisWindow->stopButton,FALSE);
-                               gtk_widget_set_sensitive(thisWindow->rewindButton,FALSE);
-                               gtk_widget_set_sensitive(thisWindow->forwardButton,FALSE);
-                               gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
-
-                               break;
-                       case CONTROL_MODE_PLAYING:
-                               gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
-
-                               gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
-
-                               break;
-                       case CONTROL_MODE_STOPPED:
-                               gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
-
-                               gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
-
-                               break;
-                       case CONTROL_MODE_PAUSED:
-                               gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
-
-                               gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
-                               gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
-
-                               break;
+    gboolean ret = TRUE;
+    gchar *uri = NULL;
+    gchar *file = NULL;
+       GUIWindow *thisWindow = (GUIWindow *)data;
+       GtkWidget *fileChooser = gtk_file_chooser_dialog_new ("Open",
+                             GTK_WINDOW(thisWindow->window),
+                                        GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OPEN,
+                                        GTK_RESPONSE_OK, GTK_STOCK_CANCEL, 
+                             GTK_RESPONSE_CANCEL, NULL);
+       gtk_window_set_modal (GTK_WINDOW (fileChooser),TRUE);
+       gtk_window_set_destroy_with_parent (GTK_WINDOW (fileChooser),TRUE);
+       gtk_widget_set_sensitive (thisWindow->window,FALSE);
+       
+       if (GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (fileChooser))) {
+               
+               file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(fileChooser));
+        if (ERR_SUCCESS != setAbsolutePathname (file, &uri)) {
+            ret = FALSE;
+            goto last;
+        }
+               if (DECODE_MODE_SINGLE == decodeMode) {
+            filename[DECODER_INDEX_SINGLE] = uri;
+                       setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PLAYING,
+                                              window[DECODER_INDEX_SINGLE]->activeFlag);
+                       setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PLAYING,
+                                              window[DECODER_INDEX_DOUBLE]->activeFlag);
+                       DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], 
+                                  filename[DECODER_INDEX_SINGLE], SEEK_START);
+               }
+        else {
+            filename[DECODER_INDEX_SINGLE] = uri;
+                       if (window[DECODER_INDEX_SINGLE] == thisWindow) {
+                               setControlMode (window[DECODER_INDEX_SINGLE], 
+                               CONTROL_MODE_PLAYING,
+                                                      window[DECODER_INDEX_SINGLE]->activeFlag);
+                               DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE],
+                                                             filename[DECODER_INDEX_SINGLE], SEEK_START);
+                       }
+            else {
+                filename[DECODER_INDEX_DOUBLE] = uri;   
+                               setControlMode (window[DECODER_INDEX_DOUBLE], 
+                                CONTROL_MODE_PLAYING,
+                                                       window[DECODER_INDEX_DOUBLE]->activeFlag);
+                               DualDecode_playMedia (pipes[DECODER_INDEX_DOUBLE],
+                                                             filename[DECODER_INDEX_DOUBLE],
+                                                             SEEK_START);
+                       }
                }
        }
-       switch(modeFlag){
-               case CONTROL_MODE_NO_FILE:
-                       gtk_widget_show(thisWindow->playButton);
-                       gtk_widget_hide(thisWindow->pauseButton);
-
-                       gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
-                                       LABEL_TEXT_NO_FILE);
-                       gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
-                                       TIME_LABEL_ORIGIN);
-                       break;
-               case CONTROL_MODE_PLAYING:
-                       gtk_widget_show(thisWindow->pauseButton);
-                       gtk_widget_hide(thisWindow->playButton);
-
-                       gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
-                                       LABEL_TEXT_PLAYING);
-                       gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
-                                       TIME_LABEL_ORIGIN);
-                       break;
-               case CONTROL_MODE_STOPPED:
-                       gtk_widget_show(thisWindow->playButton);
-                       gtk_widget_hide(thisWindow->pauseButton);
-
-                       gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
-                                       LABEL_TEXT_STOPPED);
-                       gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
-                                       TIME_LABEL_ORIGIN);
-                       break;
-               case CONTROL_MODE_PAUSED:
-                       gtk_widget_show(thisWindow->playButton);
-                       gtk_widget_hide(thisWindow->pauseButton);
+       if (GTK_IS_WIDGET (fileChooser))
+               gtk_widget_destroy (fileChooser);
 
-                       gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
-                                       LABEL_TEXT_PAUSED);
-                       break;
+       if (GTK_IS_WIDGET (thisWindow->window))
+               gtk_widget_set_sensitive (thisWindow->window,TRUE);
 
-       }
+last:    return ret;
 }
 
-static void setDecodeSwitch(gint decodeSwitch)
+/*Play Button Clicked Callback Function*/
+static gboolean cbPlayClicked (GtkWidget *widget, gpointer data)
 {
-       switch(decodeSwitch){
-               case DECODE_MODE_SINGLE:
-                       gtk_button_set_label(
-                                       GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
-                                       SWITCH_TEXT_SINGLE);
-                       gtk_button_set_label(
-                                       GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
-                                       SWITCH_TEXT_SINGLE);
-                       break;
-               case DECODE_MODE_DUAL:
-                       gtk_button_set_label(
-                                       GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
-                                       SWITCH_TEXT_DUAL);
-                       gtk_button_set_label(
-                                       GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
-                                       SWITCH_TEXT_DUAL);
+       gboolean ret = TRUE;
+    GUIWindow *thisWindow = (GUIWindow *)data;
+
+       if (DECODE_MODE_SINGLE == decodeMode) {
+               setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PLAYING,
+                                       window[DECODER_INDEX_SINGLE]->activeFlag);
+               setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PLAYING,
+                                       window[DECODER_INDEX_DOUBLE]->activeFlag);
+               if (GST_STATE_PAUSED == 
+                               DualDecode_getMediaState (pipes[DECODER_INDEX_SINGLE])) {
+                       DualDecode_resumeMedia (pipes[DECODER_INDEX_SINGLE]);
+               }
+        else {
+                       DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE],
+                                  filename[DECODER_INDEX_SINGLE], SEEK_START);
+        }
+       }
+    else {
+               if (window[DECODER_INDEX_SINGLE] == thisWindow) {
+                       setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PLAYING,
+                                               window[DECODER_INDEX_SINGLE]->activeFlag);
+                       if (GST_STATE_PAUSED == 
+                                       DualDecode_getMediaState (pipes[DECODER_INDEX_SINGLE])) {
+                               DualDecode_resumeMedia (pipes[DECODER_INDEX_SINGLE]);
+                       }
+            else if (GST_STATE_READY == 
+                      DualDecode_getMediaState (pipes[DECODER_INDEX_SINGLE])) {
+               g_print ("\nPipeline state is READY\n");
+               DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
+                                                 window[DECODER_INDEX_SINGLE]->sink, 
+                                                 NULL); 
+               DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], filename[0],0);
+            }
+
+            else {
+                                 DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], 
+                                        filename[DECODER_INDEX_SINGLE], 
+                                        SEEK_START);
+                       }
+               }
+        else {
+                       setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PLAYING,
+                                               window[DECODER_INDEX_DOUBLE]->activeFlag);
+                       if (GST_STATE_PAUSED == 
+                                       DualDecode_getMediaState (pipes[DECODER_INDEX_DOUBLE])) {
+                               DualDecode_resumeMedia (pipes[DECODER_INDEX_DOUBLE]);
+                       }
+            else if (GST_STATE_READY ==                                        
+                     DualDecode_getMediaState (pipes[DECODER_INDEX_DOUBLE])) {
+               DualDecode_resumeMedia (pipes[DECODER_INDEX_DOUBLE]);            
+            }   
+
+            else {
+                               DualDecode_playMedia (pipes[DECODER_INDEX_DOUBLE],
+                                                             filename[DECODER_INDEX_DOUBLE],
+                                      SEEK_START);
+                       }
+               }
        }
+    return ret;
 }
 
-static void setup()
+/*Pause Button Clicked Callback Function*/
+static gboolean cbPauseClicked (GtkWidget *widget, gpointer data)
 {
-       gtk_widget_show_all(window[DECODER_INDEX_SINGLE]->window);
-       gtk_widget_show_all(window[DECODER_INDEX_DOUBLE]->window);
-
-       switch(decodeMode){
-               case DECODE_MODE_NONE:
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_NO_FILE,
-                                       CONTROL_MODE_ACTIVE);
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_NO_FILE,
-                                       CONTROL_MODE_ACTIVE);
-                       decodeMode = DECODE_MODE_DUAL;
-                       setDecodeSwitch(DECODE_MODE_SINGLE);
-                       break;
-               case DECODE_MODE_SINGLE:
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_INACTIVE);
-                       DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                       filename[DECODER_INDEX_SINGLE],
-                                       SEEK_START,
-                                       window[DECODER_INDEX_SINGLE]->drawArea,
-                                       window[DECODER_INDEX_DOUBLE]->drawArea);
-                       setDecodeSwitch(DECODE_MODE_DUAL);
-                       break;
-               case DECODE_MODE_DUAL:
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                       filename[DECODER_INDEX_SINGLE],
-                                       SEEK_START,
-                                       window[DECODER_INDEX_SINGLE]->drawArea,
-                                       NULL);
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_playMedia (pipes[DECODER_INDEX_DOUBLE],
-                                       filename[DECODER_INDEX_DOUBLE],
-                                       SEEK_START,
-                                       window[DECODER_INDEX_DOUBLE]->drawArea,
-                                       NULL);
-                       setDecodeSwitch(DECODE_MODE_SINGLE);
-                       break;
+       gboolean ret = TRUE;
+    GUIWindow *thisWindow = (GUIWindow *)data;
+
+       if (DECODE_MODE_SINGLE == decodeMode) {
+               setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PAUSED,
+                                       window[DECODER_INDEX_SINGLE]->activeFlag);
+               setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PAUSED,
+                                       window[DECODER_INDEX_DOUBLE]->activeFlag);
+               DualDecode_pauseMedia (pipes[DECODER_INDEX_SINGLE]);
        }
+    else {
+               if (window[DECODER_INDEX_SINGLE] == thisWindow) {
+                       setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PAUSED,
+                                               window[DECODER_INDEX_SINGLE]->activeFlag);
+                       DualDecode_pauseMedia (pipes[DECODER_INDEX_SINGLE]);
+               }
+        else {
+                       setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PAUSED,
+                                               window[DECODER_INDEX_DOUBLE]->activeFlag);
+                       DualDecode_pauseMedia (pipes[DECODER_INDEX_DOUBLE]);
+               }
+       } 
+    return ret;
 }
 
-static gboolean cbOpenClicked(GtkWidget *widget, gpointer data)
+/*Stop Button Clicked Callback Function*/
+static gboolean cbStopClicked (GtkWidget *widget, gpointer data)
 {
-       GUIWindow *thisWindow = (GUIWindow *)data;
-
-       GtkWidget *fileChooser = gtk_file_chooser_dialog_new(
-                       "Open",
-                       GTK_WINDOW(thisWindow->window),
-                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                       GTK_STOCK_OPEN,
-                       GTK_RESPONSE_OK,
-                       GTK_STOCK_CANCEL,
-                       GTK_RESPONSE_CANCEL,
-                       NULL);
-       gtk_window_set_modal(fileChooser,FALSE);
-       if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(fileChooser))){
-               g_printerr("%s\n",
-                               gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser)));
-               /*TODO : set global filename here*/
-
-               if(DECODE_MODE_SINGLE == decodeMode){
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_INACTIVE);
-                       DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                       filename[DECODER_INDEX_SINGLE],
-                                       SEEK_START,
-                                       window[DECODER_INDEX_SINGLE]->drawArea,
-                                       window[DECODER_INDEX_DOUBLE]->drawArea);
-               }else{
-                       if(window[DECODER_INDEX_SINGLE] == thisWindow){
-                               setControlMode(window[DECODER_INDEX_SINGLE],
-                                               CONTROL_MODE_PLAYING,
-                                               CONTROL_MODE_ACTIVE);
-                               DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                               filename[DECODER_INDEX_SINGLE],
-                                               SEEK_START,
-                                               window[DECODER_INDEX_SINGLE]->drawArea,
-                                               NULL);
-                       }else{
-                               setControlMode(window[DECODER_INDEX_DOUBLE],
-                                               CONTROL_MODE_PLAYING,
-                                               CONTROL_MODE_ACTIVE);
-                               DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
-                                               filename[DECODER_INDEX_DOUBLE],
-                                               SEEK_START,
-                                               window[DECODER_INDEX_DOUBLE]->drawArea,
-                                               NULL);
-                       }
+       gboolean ret = TRUE;
+    GUIWindow *thisWindow = (GUIWindow *)data;
+   
+
+       if (DECODE_MODE_SINGLE == decodeMode) {
+               setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_STOPPED,
+                                       window[DECODER_INDEX_SINGLE]->activeFlag);
+               setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_STOPPED,
+                                       window[DECODER_INDEX_DOUBLE]->activeFlag);
+               DualDecode_stopMedia (pipes[DECODER_INDEX_SINGLE]);
+       }
+    else {
+               if (window[DECODER_INDEX_SINGLE] == thisWindow) {
+                       setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_STOPPED,
+                                               window[DECODER_INDEX_SINGLE]->activeFlag);
+                       DualDecode_stopMedia (pipes[DECODER_INDEX_SINGLE]);
+               }
+        else {
+                       setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_STOPPED,
+                                               window[DECODER_INDEX_DOUBLE]->activeFlag);
+                       DualDecode_stopMedia (pipes[DECODER_INDEX_DOUBLE]);
                }
        }
-       gtk_widget_destroy(fileChooser);
+    return ret;
+}
+static gboolean cbForwardClicked (GtkWidget *widget, gpointer data)                 
+{                                                                               
+    gboolean ret = TRUE;                                                        
+    GstFormat format = GST_FORMAT_TIME;                                         
+    gint64 duration = 0;                                                        
+    gint64 seekPoint = 0;                                                         
+    GUIWindow *thisWindow = (GUIWindow *)data;               
+    gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));                   
+                                                                                
+    g_print ("IN FORWARD CLICKED\n");                                        
+    if (DECODE_MODE_SINGLE == decodeMode) {                                      
+                                                                                
+        gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,          
+                                    &format,&duration);                         
+        seekPoint =  (duration * percent/ (gdouble)100)+ FORWARD;                
+        g_print ("SEEK POINT %ld\n", seekPoint);                                 
+        ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint);     
+    }                                                                           
+    else {                                                                       
+        if (window[DECODER_INDEX_SINGLE] == thisWindow) {                         
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
+                                        &format, &duration);                     
+            seekPoint =  (duration * percent/ (gdouble)100) + FORWARD;
+            g_print ("SEEK POINT %ld\n", seekPoint);            
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint); 
+        }                                                                       
+        else {                                                                  
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,       
+                                       &format,&duration);                      
+            seekPoint = (duration * percent/ (gdouble)100)+ FORWARD;            
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_DOUBLE], seekPoint); 
+        }                                                                       
+    }                                                                           
+                                                                                
+        return ret; 
+}                                                                                
+static gboolean cbRewindClicked (GtkWidget *widget, gpointer data)                 
+{
+    gboolean ret = TRUE;                                                        
+    GstFormat format = GST_FORMAT_TIME;                                         
+    gint64 duration = 0;                                                        
+    gint64 seekPoint = 0;                                                       
+    GUIWindow *thisWindow = (GUIWindow *)data;                                  
+    gdouble percent = gtk_range_get_value ((GtkRange *) (thisWindow->seekScale));
+                                                                                
+    g_print ("IN FORWARD CLICKED\n");                                           
+    if (DECODE_MODE_SINGLE == decodeMode) {                                      
+                                                                                
+        gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,          
+                                    &format,&duration);                         
+        seekPoint =  (duration * percent/ (gdouble)100) - REWIND;               
+        g_print ("SEEK POINT %ld\n", seekPoint);
+        seekPoint = (seekPoint < 0) ? 0 : seekPoint;                                 
+        ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint);     
+    }                                                                           
+    else {                                                                       
+        if (window[DECODER_INDEX_SINGLE] == thisWindow) {                         
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,      
+                                        &format, &duration);                    
+            seekPoint =  (duration * percent/ (gdouble)100) - REWIND;          
+            g_print ("SEEK POINT %ld\n", seekPoint);
+            seekPoint = (seekPoint < 0) ? 0 : seekPoint;                             
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_SINGLE], seekPoint); 
+        }                                                                       
+        else {                                                                  
+            gst_element_query_duration (pipes[DECODER_INDEX_SINGLE]->pipe,       
+                                       &format,&duration);                      
+            seekPoint = (duration * percent/ (gdouble)100) - REWIND;    
+            seekPoint = (seekPoint < 0) ? 0 : seekPoint;        
+            ret = DualDecode_seekMedia (pipes[DECODER_INDEX_DOUBLE], seekPoint); 
+        }                                                                       
+    }                                                                           
+                                                                                
+        return ret;                                                                                  
+}    
+static gboolean cbSwitchButtonClicked (GtkWidget *widget, gpointer data)
+{
+    gboolean ret = TRUE;
+    gboolean noFile = FALSE;
+    GUIWindow *thisWindow = (GUIWindow *) data;
+    gint otherWindowIndex = 0;
+    gint thisWindowIndex = 0;
+
+    /*No file is given yet to play. Application may be just started. */
+    if (NULL == filename[DECODER_INDEX_SINGLE])
+        noFile = TRUE;
+
+    if (thisWindow == window[DECODER_INDEX_SINGLE]) {
+        thisWindowIndex = DECODER_INDEX_SINGLE;
+        otherWindowIndex = DECODER_INDEX_DOUBLE;
+    }
+    else 
+    {
+        otherWindowIndex = DECODER_INDEX_SINGLE;
+        thisWindowIndex = DECODER_INDEX_DOUBLE;
+    }
+
+    switch (decodeMode) {
+    case DECODE_MODE_SINGLE :  
+        setControlMode (window[otherWindowIndex], 
+                        window[otherWindowIndex]->modeFlag, CONTROL_MODE_ACTIVE);
+        setControlMode (thisWindow, thisWindow->modeFlag, CONTROL_MODE_ACTIVE);
+
+        if (FALSE == noFile) {
+          ret = DualDecode_singleToDual (pipes,
+                                         window[otherWindowIndex]->sink,
+                                         thisWindowIndex, otherWindowIndex, 
+                                         filename[DECODER_INDEX_SINGLE]);
+        }
+        decodeMode = DECODE_MODE_DUAL;
+        setDecodeSwitch(DECODE_MODE_SINGLE);
+        break;
+
+    case DECODE_MODE_DUAL :      
+        setControlMode (window[otherWindowIndex], thisWindow->modeFlag, 
+                          CONTROL_MODE_INACTIVE);  
+
+        if (FALSE == noFile) {
+        ret = DualDecode_dualToSingle (pipes,
+                                       window[otherWindowIndex]->sink,        
+                                         thisWindowIndex, otherWindowIndex);
+         }
+         decodeMode = DECODE_MODE_SINGLE; 
+         setDecodeSwitch (DECODE_MODE_DUAL);     
+         break;
+    } 
+
+
+    return ret;
+}
+/*Window Close Callback Function*/
+static gboolean cbWindowClosed (GtkWidget *widget, gpointer data){
+       DualDecode_exitApplication();
+    return TRUE;
+}
+
+static gboolean cbHelpClicked (GtkWidget *widget, gpointer data){
+    g_print ("HELP BUTTON CLICKED\n");
+    gtk_widget_show (helpWindow);
+    return TRUE;
+}
+
+static gboolean cbHelpClosed (GtkWidget *widget, gpointer data){
+    g_print ("IN HELP CLOSED\n");
+    gtk_widget_hide (helpWindow);
+    return TRUE;
 }
+/******************************************************************************
+                       Static utility functions definition
 
-static gboolean cbPlayClicked(GtkWidget *widget, gpointer data)
+ ******************************************************************************/
+static void setControlActive (GUIWindow *window, gboolean activeFlag)
 {
-       GUIWindow *thisWindow = (GUIWindow *)data;
+       gtk_widget_set_sensitive (window->playButton,activeFlag);
+       gtk_widget_set_sensitive (window->pauseButton,activeFlag);
+       gtk_widget_set_sensitive (window->stopButton,activeFlag);
+       gtk_widget_set_sensitive (window->rewindButton,activeFlag);
+       gtk_widget_set_sensitive (window->forwardButton,activeFlag);
+       gtk_widget_set_sensitive (window->openButton,activeFlag);
+       gtk_widget_set_sensitive (window->seekScale,activeFlag);
+    gtk_widget_set_sensitive (window->switchButton, activeFlag);
+    
+}
 
-       if(DECODE_MODE_SINGLE == decodeMode){
-               setControlMode(window[DECODER_INDEX_SINGLE],
-                               CONTROL_MODE_PLAYING,
-                               CONTROL_MODE_ACTIVE);
-               setControlMode(window[DECODER_INDEX_DOUBLE],
-                               CONTROL_MODE_PLAYING,
-                               CONTROL_MODE_INACTIVE);
-               if(GST_STATE_PAUSED == 
-                               DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
-                       DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
-               }else{
-                       DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                       filename[DECODER_INDEX_SINGLE],
-                                       SEEK_START,
-                                       window[DECODER_INDEX_SINGLE]->drawArea,
-                                       window[DECODER_INDEX_DOUBLE]->drawArea);
-               }
-       }else{
-               if(window[DECODER_INDEX_SINGLE] == thisWindow){
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       if(GST_STATE_PAUSED == 
-                                       DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
-                               DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
-                       }else{
-                               DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
-                                               filename[DECODER_INDEX_SINGLE],
-                                               SEEK_START,
-                                               window[DECODER_INDEX_SINGLE]->drawArea,
-                                               NULL);
-                       }
-               }else{
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_PLAYING,
-                                       CONTROL_MODE_ACTIVE);
-                       if(GST_STATE_PAUSED == 
-                                       DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
-                               DualDecode_resumeMedia(pipes[DECODER_INDEX_DOUBLE]);
-                       }else{
-                               DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
-                                               filename[DECODER_INDEX_DOUBLE],
-                                               SEEK_START,
-                                               window[DECODER_INDEX_DOUBLE]->drawArea,
-                                               NULL);
-                       }
+static void setControlMode (GUIWindow *thisWindow, gint modeFlag, 
+                            gint activeFlag)
+{
+       setControlActive (thisWindow, activeFlag);
+       if (activeFlag) {
+               switch (modeFlag) {
+           case CONTROL_MODE_NO_FILE:
+                   gtk_widget_set_sensitive (thisWindow->playButton,FALSE);
+                       gtk_widget_set_sensitive (thisWindow->pauseButton,FALSE);
+                       gtk_widget_set_sensitive (thisWindow->stopButton,FALSE);
+                       gtk_widget_set_sensitive (thisWindow->rewindButton,FALSE);
+                       gtk_widget_set_sensitive (thisWindow->forwardButton,FALSE);
+                       gtk_widget_set_sensitive (thisWindow->seekScale,FALSE);
+                       break;
+               case CONTROL_MODE_PLAYING:
+                       gtk_widget_set_sensitive (thisWindow->playButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->pauseButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->stopButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->rewindButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->forwardButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->seekScale,TRUE);
+               break; 
+               case CONTROL_MODE_STOPPED:
+                   gtk_widget_set_sensitive (thisWindow->playButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->pauseButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->stopButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->rewindButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->forwardButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->seekScale,FALSE);
+                       break;
+               case CONTROL_MODE_PAUSED:
+                       gtk_widget_set_sensitive (thisWindow->playButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->pauseButton,TRUE);
+               gtk_widget_set_sensitive (thisWindow->stopButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->rewindButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->forwardButton,TRUE);
+                       gtk_widget_set_sensitive (thisWindow->seekScale,TRUE);
+               break;
                }
        }
-}
+       switch (modeFlag) {
+       case CONTROL_MODE_NO_FILE:
+               gtk_widget_show (thisWindow->playButton);
+               gtk_widget_hide (thisWindow->pauseButton);
 
-static gboolean cbPauseClicked(GtkWidget *widget, gpointer data)
-{
-       GUIWindow *thisWindow = (GUIWindow *)data;
+               gtk_label_set_text (GTK_LABEL(thisWindow->statusLabel),
+                                       LABEL_TEXT_NO_FILE);
+               gtk_label_set_text (GTK_LABEL(thisWindow->timeLabel),
+                                       TIME_LABEL_ORIGIN);
+               if (thisWindow->timerSignal != TIMER_SIGNAL_NONE) {
+                   g_source_remove (thisWindow->timerSignal);
+                       thisWindow->timerSignal = TIMER_SIGNAL_NONE;
+               }
+               break;
+       case CONTROL_MODE_PLAYING:
+               gtk_widget_show (thisWindow->pauseButton);
+               gtk_widget_hide (thisWindow->playButton);
 
-       if(DECODE_MODE_SINGLE == decodeMode){
-               setControlMode(window[DECODER_INDEX_SINGLE],
-                               CONTROL_MODE_PAUSED,
-                               CONTROL_MODE_ACTIVE);
-               setControlMode(window[DECODER_INDEX_DOUBLE],
-                               CONTROL_MODE_PAUSED,
-                               CONTROL_MODE_INACTIVE);
-               DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
-       }else{
-               if(window[DECODER_INDEX_SINGLE] == thisWindow){
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_PAUSED,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
-               }else{
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_PAUSED,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_pauseMedia(pipes[DECODER_INDEX_DOUBLE]);
+               gtk_label_set_text (GTK_LABEL(thisWindow->statusLabel),
+                                       LABEL_TEXT_PLAYING);
+               gtk_label_set_text (GTK_LABEL(thisWindow->timeLabel),
+                                       TIME_LABEL_ORIGIN);
+
+               if (thisWindow->timerSignal != TIMER_SIGNAL_NONE) {
+                               g_source_remove (thisWindow->timerSignal);
+        }
+               thisWindow->timerSignal = g_timeout_add (TIMER_INTERVAL, cbTimerInterval,
+                                                                       thisWindow); 
+                       
+               break;
+       case CONTROL_MODE_STOPPED:
+               gtk_widget_show (thisWindow->playButton);
+               gtk_widget_hide (thisWindow->pauseButton);
+
+               gtk_label_set_text (GTK_LABEL(thisWindow->statusLabel), 
+                            LABEL_TEXT_STOPPED);
+               gtk_label_set_text (GTK_LABEL(thisWindow->timeLabel), TIME_LABEL_ORIGIN);
+
+               if (thisWindow->timerSignal != TIMER_SIGNAL_NONE) {
+                       g_source_remove(thisWindow->timerSignal);
+                       thisWindow->timerSignal = TIMER_SIGNAL_NONE;
                }
+               break;
+       case CONTROL_MODE_PAUSED:
+               gtk_widget_show(thisWindow->playButton);
+               gtk_widget_hide(thisWindow->pauseButton);
+
+               gtk_label_set_text (GTK_LABEL (thisWindow->statusLabel), 
+                            LABEL_TEXT_PAUSED);
+           break;
+
        }
+       thisWindow->modeFlag = modeFlag;
+       thisWindow->activeFlag = activeFlag;
 }
 
-static gboolean cbStopClicked(GtkWidget *widget, gpointer data)
+static void setDecodeSwitch (gint decodeSwitch)
 {
-       GUIWindow *thisWindow = (GUIWindow *)data;
-
-       if(DECODE_MODE_SINGLE == decodeMode){
-               setControlMode(window[DECODER_INDEX_SINGLE],
-                               CONTROL_MODE_STOPPED,
-                               CONTROL_MODE_ACTIVE);
-               setControlMode(window[DECODER_INDEX_DOUBLE],
-                               CONTROL_MODE_STOPPED,
-                               CONTROL_MODE_INACTIVE);
-               DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
-       }else{
-               if(window[DECODER_INDEX_SINGLE] == thisWindow){
-                       setControlMode(window[DECODER_INDEX_SINGLE],
-                                       CONTROL_MODE_STOPPED,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
-               }else{
-                       setControlMode(window[DECODER_INDEX_DOUBLE],
-                                       CONTROL_MODE_STOPPED,
-                                       CONTROL_MODE_ACTIVE);
-                       DualDecode_stopMedia(pipes[DECODER_INDEX_DOUBLE]);
-               }
+       switch (decodeSwitch) {
+       case DECODE_MODE_SINGLE:
+               gtk_button_set_label (
+                                       GTK_BUTTON (window[DECODER_INDEX_SINGLE]->switchButton),
+                                       SWITCH_TEXT_SINGLE);
+               gtk_button_set_label (
+                                       GTK_BUTTON (window[DECODER_INDEX_DOUBLE]->switchButton),
+                                       SWITCH_TEXT_SINGLE);
+               break;
+       case DECODE_MODE_DUAL:
+               gtk_button_set_label (
+                                       GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
+                                       SWITCH_TEXT_DUAL);
+               gtk_button_set_label (
+                                       GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
+                                       SWITCH_TEXT_DUAL);
        }
 }
 
-static gboolean cbWindowClosed(GtkWidget *widget, gpointer data){
-       DualDecode_exitApplication();
+static void setup()
+{
+
+    g_print ("SINK TO BE USED %s\n", sink);
+       gtk_widget_show_all (window[DECODER_INDEX_SINGLE]->window);
+       gtk_widget_show_all (window[DECODER_INDEX_DOUBLE]->window);
+
+    window[DECODER_INDEX_SINGLE]->sink = createImageSinkFromWindow (            
+                                        window[DECODER_INDEX_SINGLE]->drawArea, 
+                                        "windowsink0"); 
+
+    window[DECODER_INDEX_DOUBLE]->sink = createImageSinkFromWindow (           
+                                        window[DECODER_INDEX_DOUBLE]->drawArea, 
+                                        "windowsink1"); 
+
+    /*If any of the sinks is NULL the application exits*/
+
+    if (NULL == window[DECODER_INDEX_SINGLE]->sink || 
+        NULL == window[DECODER_INDEX_DOUBLE]->sink) {
+            DualDecode_exitApplication();
+    
+    }
+       switch (decodeMode) {
+       case DECODE_MODE_NONE:
+               setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_NO_FILE,
+                                       CONTROL_MODE_ACTIVE);
+               setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_NO_FILE,
+                                       CONTROL_MODE_ACTIVE);
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
+                                    window[DECODER_INDEX_SINGLE]->sink, NULL);                            
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], 
+                                    window[DECODER_INDEX_DOUBLE]->sink, NULL);
+           decodeMode = DECODE_MODE_DUAL;
+           setDecodeSwitch (DECODE_MODE_SINGLE);
+               break;
+       case DECODE_MODE_SINGLE:
+               setControlMode (window[DECODER_INDEX_SINGLE],
+                                   CONTROL_MODE_PLAYING, CONTROL_MODE_ACTIVE);
+               setControlMode (window[DECODER_INDEX_DOUBLE],CONTROL_MODE_PLAYING,
+                                           CONTROL_MODE_INACTIVE);
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
+                                    window[DECODER_INDEX_SINGLE]->sink,
+                                    window[DECODER_INDEX_DOUBLE]->sink);
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], NULL, NULL);
+           DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE], 
+                              filename[DECODER_INDEX_SINGLE], SEEK_START);
+               setDecodeSwitch (DECODE_MODE_DUAL);
+               break;
+       case DECODE_MODE_DUAL:
+               setControlMode (window[DECODER_INDEX_SINGLE], CONTROL_MODE_PLAYING,
+                                          CONTROL_MODE_ACTIVE);
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_SINGLE], 
+                                    window[DECODER_INDEX_SINGLE]->sink, NULL);
+        DualDecode_setPipelineSink (pipes[DECODER_INDEX_DOUBLE], 
+                                    window[DECODER_INDEX_DOUBLE]->sink, NULL);
+
+               DualDecode_playMedia (pipes[DECODER_INDEX_SINGLE],
+                              filename[DECODER_INDEX_SINGLE], SEEK_START);
+               setControlMode (window[DECODER_INDEX_DOUBLE], CONTROL_MODE_PLAYING,
+                                           CONTROL_MODE_ACTIVE);
+               DualDecode_playMedia (pipes[DECODER_INDEX_DOUBLE], 
+                              filename[DECODER_INDEX_DOUBLE], SEEK_START);
+               setDecodeSwitch (DECODE_MODE_SINGLE);
+               break;
+       }
 }
 
 static GUIWindow *createWindow()
 {
        GUIWindow *ret  = NULL;
-       ret = g_malloc0(sizeof(GUIWindow));
+       ret = g_malloc0 (sizeof(GUIWindow));
        if(NULL == ret){
                return ret;
        }
-       DualDecode_builderCreate();
+       DualDecode_builderCreate ();
 
-       ret->window = DualDecode_getWidget("decodeWindowSingle");
-       if(NULL == ret->window){
+       ret->window = DualDecode_getWidget ("decodeWindowSingle");
+       if (NULL == ret->window) {
                goto memCleanup;
        }
        ret->windowCloseSignal = g_signal_connect(G_OBJECT(ret->window),
@@ -417,149 +787,158 @@ static GUIWindow *createWindow()
                        G_CALLBACK(cbWindowClosed),
                        NULL);
 
-       GtkWidget *toolbar = DualDecode_getWidget("toolbarSingle");
-       if(NULL == toolbar){
+       GtkWidget *toolbar = DualDecode_getWidget ("toolbarSingle");
+       if (NULL == toolbar) {
                goto memCleanup;
        }
-       ret->drawArea = DualDecode_getWidget("videoViewerSingle");
-       if(NULL == ret->drawArea){
+       ret->drawArea = DualDecode_getWidget ("videoViewerSingle");
+       if (NULL == ret->drawArea) {
                goto memCleanup;
        }
 
-       ret->openButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_OPEN));
-       if(NULL == ret->openButton){
+       ret->openButton = GTK_WIDGET (
+                      gtk_tool_button_new_from_stock(GTK_STOCK_OPEN));
+       if (NULL == ret->openButton) {
                goto memCleanup;
        }
-       ret->rewindButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND));
-       if(NULL == ret->rewindButton){
+       ret->rewindButton = GTK_WIDGET (
+                                   gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND));
+       if (NULL == ret->rewindButton) {
                goto memCleanup;
        }
-       ret->playButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY));
-       if(NULL == ret->playButton){
+       ret->playButton = GTK_WIDGET (
+                                 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY));
+       if (NULL == ret->playButton) {
                goto memCleanup;
        }
-       ret->pauseButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE));
-       if(NULL == ret->pauseButton){
+       ret->pauseButton = GTK_WIDGET (
+                                  gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE));
+       if (NULL == ret->pauseButton) {
                goto memCleanup;
        }
-       ret->stopButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP));
-       if(NULL == ret->stopButton){
+       ret->stopButton = GTK_WIDGET (
+                                 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP));
+       if (NULL == ret->stopButton) {
                goto memCleanup;
        }
-       ret->forwardButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD));
-       if(NULL == ret->forwardButton){
+       ret->forwardButton = GTK_WIDGET (
+                                    gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD));
+       if (NULL == ret->forwardButton) {
                goto memCleanup;
        }
-       ret->helpButton = GTK_WIDGET(
-                       gtk_tool_button_new_from_stock(GTK_STOCK_HELP));
-       if(NULL == ret->helpButton){
+       ret->helpButton = GTK_WIDGET (
+                                 gtk_tool_button_new_from_stock(GTK_STOCK_HELP));
+       if (NULL == ret->helpButton) {
                goto memCleanup;
        }
 
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->openButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       gtk_separator_tool_item_new(),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->rewindButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->playButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->pauseButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->stopButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->forwardButton),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       gtk_separator_tool_item_new(),
-                       -1);
-       gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
-                       GTK_TOOL_ITEM(ret->helpButton),
-                       -1);
-
-       ret->openSignal = g_signal_connect(G_OBJECT(ret->openButton),
-                       "clicked",
-                       G_CALLBACK(cbOpenClicked),
-                       ret);
-       ret->stopSignal = g_signal_connect(G_OBJECT(ret->stopButton),
-                       "clicked",
-                       G_CALLBACK(cbStopClicked),
-                       ret);
-       ret->pauseSignal = g_signal_connect(G_OBJECT(ret->pauseButton),
-                       "clicked",
-                       G_CALLBACK(cbPauseClicked),
-                       ret);
-       ret->playSignal = g_signal_connect(G_OBJECT(ret->playButton),
-                       "clicked",
-                       G_CALLBACK(cbPlayClicked),
+       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (ret->openButton),
+                                  -1);
+       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), gtk_separator_tool_item_new(),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(ret->rewindButton),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(ret->playButton),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(ret->pauseButton),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(ret->stopButton),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(ret->forwardButton),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(),
+                                   -1);
+       gtk_toolbar_insert (GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(ret->helpButton),
+                                   -1);
+
+       ret->openSignal = g_signal_connect (G_OBJECT (ret->openButton), "clicked",
+                                                   G_CALLBACK (cbOpenClicked), ret);
+       ret->stopSignal = g_signal_connect (G_OBJECT (ret->stopButton), "clicked",
+                                                   G_CALLBACK (cbStopClicked), ret);
+       ret->pauseSignal = g_signal_connect (G_OBJECT (ret->pauseButton), "clicked",
+                                                    G_CALLBACK (cbPauseClicked), ret);
+       ret->playSignal = g_signal_connect (G_OBJECT (ret->playButton), "clicked",
+                                                   G_CALLBACK (cbPlayClicked),
                        ret);
+    ret->forwardSignal = g_signal_connect (G_OBJECT (ret->forwardButton),"clicked",                                                          
+                                           G_CALLBACK (cbForwardClicked), ret);
+    ret->rewindSignal = g_signal_connect (G_OBJECT (ret->rewindButton),"clicked",                                                          
+                                          G_CALLBACK (cbRewindClicked), ret);
+
+    ret->helpSignal = g_signal_connect (G_OBJECT (ret->helpButton), "clicked",                                                          
+                                        G_CALLBACK(cbHelpClicked), ret);   
+
 
-       ret->switchButton = DualDecode_getWidget("switchButtonSingle");
-       if(NULL == ret->switchButton){
+       ret->switchButton = DualDecode_getWidget ("switchButtonSingle");
+       if (NULL == ret->switchButton) {
                goto memCleanup;
        }
 
-       /*TODO: connect switch signal here*/
+       ret->switchSignal = g_signal_connect (G_OBJECT (ret->switchButton), "clicked",
+                                          G_CALLBACK (cbSwitchButtonClicked),
+                                          ret);
 
-       ret->seekScale = DualDecode_getWidget("seekScaleSingle");
-       if(NULL == ret->seekScale){
+       ret->seekScale = DualDecode_getWidget ("seekScaleSingle");
+       if (NULL == ret->seekScale) {
                goto memCleanup;
        }
 
-       /*TODO: connect scale signal here*/
+    ret->seekSignal = g_signal_connect (G_OBJECT (ret->seekScale), 
+                                        "value_changed",
+                                        G_CALLBACK (cbSeekValueChanged), ret);
+       
 
-       ret->statusLabel = DualDecode_getWidget("statusLabelSingle");
-       if(NULL == ret->statusLabel){
+       ret->statusLabel = DualDecode_getWidget ("statusLabelSingle");
+       if (NULL == ret->statusLabel) {
                goto memCleanup;
        }
 
-       ret->timeLabel = DualDecode_getWidget("timeLabelSingle");
-       if(NULL == ret->timeLabel){
+       ret->timeLabel = DualDecode_getWidget ("timeLabelSingle");
+       if (NULL == ret->timeLabel) {
                goto memCleanup;
        }
+    ret->activeFlag = FALSE;
 
        goto last;
 
-cleanup:
-       gtk_widget_destroy(ret->window);
+       gtk_widget_destroy (ret->window);
 memCleanup:
-       g_free(ret);
+       g_free (ret);
 last:
-       DualDecode_builderClose();
+       DualDecode_builderClose ();
        return ret;
 }
 
-static GtkWidget *createLogWindow()
+static GtkWidget *createLogWindow ()
 {
-       /*TODO: create help window*/
-       return gtk_window_new(GTK_WINDOW_TOPLEVEL);
+       return gtk_window_new (GTK_WINDOW_TOPLEVEL);
 }
 
-static GtkWidget *createHelpWindow()
+static GtkWidget *createHelpWindow ()
 {
-       /*TODO: create help window*/
-       return gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    GtkWidget * helpWindow;
+    gint width;
+    gint height;
+
+    helpWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title ( (GtkWindow *) helpWindow, "Help");
+    gtk_window_set_resizable ( (GtkWindow * )helpWindow, FALSE);
+
+    /*Set size same as display windows*/
+    gtk_widget_get_size_request (window[DECODER_INDEX_SINGLE]->window,
+                                 &width,
+                                 &height);  
+    gtk_widget_set_size_request (helpWindow, width, height);
+    /*Connect signal to close button handler*/
+    g_signal_connect(G_OBJECT (helpWindow), "delete-event", 
+      G_CALLBACK (cbHelpClosed), NULL);
+    g_print ("RETURNING FROM CREATE HELP\n");
+    return helpWindow;
 }
 
-G_GNUC_PRINTF(2,3) static void logGUI(GtkWidget *logWindow, gchar *format, ...)
-{
-       /*TODO: dummy now*/
-}
 
-static void setWindowSizeLocation()
+                                                         
+static void setWindowSizeLocation ()
 {
        GdkScreen *screen               = NULL;
        gint screenWidth                = -1;
@@ -567,74 +946,109 @@ static void setWindowSizeLocation()
        gint windowWidth                = -1;
        gint windowHeight               = -1;
 
-       screen = gdk_screen_get_default();
-       screenWidth = gdk_screen_get_width(screen);
-       screenHeight = gdk_screen_get_height(screen);
+       screen = gdk_screen_get_default ();
+       screenWidth = gdk_screen_get_width (screen);
+       screenHeight = gdk_screen_get_height (screen);
        windowWidth = screenWidth/SCREEN_WIDTH_FACTOR;
        windowHeight = screenHeight/SCREEN_HEIGHT_FACTOR;
 
-       gtk_widget_set_size_request(window[DECODER_INDEX_SINGLE]->window,
-                       windowWidth,windowHeight);
-       gtk_widget_set_size_request(window[DECODER_INDEX_DOUBLE]->window,
-                       windowWidth,windowHeight);
-       gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_SINGLE]->window),
-                       (screenWidth-2*windowWidth)/2,
-                       0);
-       gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_DOUBLE]->window),
-                       (screenWidth-2*windowWidth)/2+windowWidth,
+       gtk_widget_set_size_request (window[DECODER_INDEX_SINGLE]->window,
+                                            windowWidth,windowHeight);
+       gtk_widget_set_size_request (window[DECODER_INDEX_DOUBLE]->window,
+                                            windowWidth,windowHeight);
+       gtk_window_move (GTK_WINDOW (window[DECODER_INDEX_SINGLE]->window),
+                                           (screenWidth - 2 * windowWidth) / 2, 0);
+       gtk_window_move (GTK_WINDOW (window[DECODER_INDEX_DOUBLE]->window),
+                                (screenWidth - 2 * windowWidth) / 2 + windowWidth,
                        0);
 }
 
-void DualDecode_startApplication()
+static GstElement *createImageSinkFromWindow (GtkWidget * window, gchar *name)
+{
+    GstElement *sinkElement = NULL;                                             
+    XID xid                 = 0;                                                
+    GdkDrawable *drawable   = NULL;                                             
+                                                                                
+    /*make an xvimagesink element from factory*/                                
+                                     
+    sinkElement = gst_element_factory_make (sink,name);                        
+    if (NULL == sinkElement) {
+        g_print ("%s sink cannot be created\n", sink);                                                           
+        goto return_pos;                                                        
+    }                                                                           
+                                                                                
+    /*get the XID of the display window's drawable*/                            
+    drawable = gtk_widget_get_window (GTK_WIDGET (window));                     
+    if (FALSE == GDK_IS_DRAWABLE (drawable)) {                                     
+        /*TODO: A BUG HERE?*/                                                   
+        g_object_unref (G_OBJECT (sinkElement));                                         
+        sinkElement=NULL;                                                              
+        goto return_pos;                                                        
+    }                                                                           
+    xid = gdk_x11_drawable_get_xid (drawable);                                   
+                                                                                
+    /*link the gst sink element to the XID*/                                    
+    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sinkElement),xid);                    
+                                                                                
+return_pos:                                                                     
+    return sinkElement;                                                                
+}   
+
+/******************************************************************************
+                                      Public Functions
+
+ ******************************************************************************/
+
+/******************************************************************************
+                                       See gui.h
+ ******************************************************************************/
+void DualDecode_startApplication ()
 {
+
        window[DECODER_INDEX_SINGLE] = createWindow();
-       g_assert(window[DECODER_INDEX_SINGLE] != NULL);
+       g_assert (window[DECODER_INDEX_SINGLE] != NULL);
 
        window[DECODER_INDEX_DOUBLE] = createWindow();
-       g_assert(window[DECODER_INDEX_DOUBLE] != NULL);
+       g_assert (window[DECODER_INDEX_DOUBLE] != NULL);
 
        setWindowSizeLocation();
 
        helpWindow = createHelpWindow();
-       g_assert(helpWindow != NULL);
-
-       logWindow[DECODER_INDEX_SINGLE] = createLogWindow();
-       g_assert(logWindow[DECODER_INDEX_SINGLE] != NULL);
-
-       logWindow[DECODER_INDEX_DOUBLE] = createLogWindow();
-       g_assert(logWindow[DECODER_INDEX_DOUBLE] != NULL);
+       g_assert (helpWindow != NULL);
 
-       pipes[DECODER_INDEX_SINGLE] = DualDecode_createPipeline();
-       DualDecode_setLogFunction(pipes[DECODER_INDEX_SINGLE],
-                       logGUI,
-                       logWindow[DECODER_INDEX_SINGLE]);
+       logWindow[DECODER_INDEX_SINGLE] = createLogWindow ();
+       g_assert (logWindow[DECODER_INDEX_SINGLE] != NULL);
 
-       pipes[DECODER_INDEX_DOUBLE] = DualDecode_createPipeline();
-       DualDecode_setLogFunction(pipes[DECODER_INDEX_DOUBLE],
-                       logGUI,
-                       logWindow[DECODER_INDEX_DOUBLE]);
+       logWindow[DECODER_INDEX_DOUBLE] = createLogWindow ();
+       g_assert (logWindow[DECODER_INDEX_DOUBLE] != NULL);
 
-       setup();
+       pipes[DECODER_INDEX_SINGLE] = DualDecode_createPipeline ();
+       pipes[DECODER_INDEX_DOUBLE] = DualDecode_createPipeline ();
+       setup ();
 
-       gtk_main();
+       gtk_main ();
+    
 }
 
 void DualDecode_exitApplication()
 {
-       gtk_widget_destroy(window[DECODER_INDEX_SINGLE]->window);
-       gtk_widget_destroy(window[DECODER_INDEX_DOUBLE]->window);
-       g_free(window[DECODER_INDEX_SINGLE]);
-       g_free(window[DECODER_INDEX_DOUBLE]);
-       gtk_widget_destroy(logWindow[DECODER_INDEX_SINGLE]);
-       gtk_widget_destroy(logWindow[DECODER_INDEX_DOUBLE]);
-       gtk_widget_destroy(helpWindow);
+       gtk_widget_destroy (window[DECODER_INDEX_SINGLE]->window);
+       gtk_widget_destroy (window[DECODER_INDEX_DOUBLE]->window);
+       g_free (window[DECODER_INDEX_SINGLE]);
+       g_free (window[DECODER_INDEX_DOUBLE]);
+       gtk_widget_destroy (logWindow[DECODER_INDEX_SINGLE]);
+       gtk_widget_destroy (logWindow[DECODER_INDEX_DOUBLE]);
+       gtk_widget_destroy (helpWindow);
 
        /*TODO: destroy pipes here*/
 
-       gtk_main_quit();
+    if (gtk_main_level())
+        gtk_main_quit ();
+    exit (0);
 }
 
 gboolean DualDecode_initGUI(gint *argc, char **argv[])
 {
-       return gtk_init_check(argc,argv);
+       return gtk_init_check (argc,argv);
 }