maemo-ui-old/src/mmyth_ui.c
branchtrunk
changeset 892 e4323b3483bf
parent 754 cb885ee44618
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/maemo-ui-old/src/mmyth_ui.c	Wed Jan 23 20:07:03 2008 +0000
     1.3 @@ -0,0 +1,894 @@
     1.4 +
     1.5 +#include <glib-object.h>
     1.6 +#include <sys/types.h>
     1.7 +#include <sys/stat.h>
     1.8 +#include <unistd.h>
     1.9 +#include <string.h>
    1.10 +#include <stdio.h>
    1.11 +#include <gtk/gtk.h>
    1.12 +#include <gdk/gdkx.h>
    1.13 +#include <gst/interfaces/xoverlay.h>
    1.14 +#include <assert.h>
    1.15 +
    1.16 +#include "mmyth_ui.h"
    1.17 +#include "mmyth_uicommon.h"
    1.18 +#include "mmyth_schedulerui.h"
    1.19 +#include "mmyth_recordui.h"
    1.20 +#include "mmyth_uisettings.h"
    1.21 +#include "mmyth_epg_grid_view.h"
    1.22 +#include "mmyth_tvplayer.h"
    1.23 +
    1.24 +/*
    1.25 + * GMyth library includes 
    1.26 + */
    1.27 +
    1.28 +#ifndef MAEMO_PLATFORM
    1.29 +static gint     button_press_handler(GtkWidget * widget, GdkEvent * event);
    1.30 +#endif
    1.31 +
    1.32 +static MMythUiCommon *create_main_view(MMythUi * mmyth_ui);
    1.33 +static MMythUiCommon *create_video_view(MMythUi * mmyth_ui);
    1.34 +static MMythUiCommon *create_epg_grid_view(MMythUi * mmyth_ui);
    1.35 +static MMythUiCommon *create_record_view(MMythUi * mmyth_ui);
    1.36 +static MMythUiCommon *create_schedule_view(MMythUi * mmyth_ui);
    1.37 +
    1.38 +static void     cb_video_close_button(GtkButton * button,
    1.39 +                                      gpointer user_data);
    1.40 +static void     cb_record_button(GtkButton * button, gpointer user_data);
    1.41 +static void     cb_menu_item_settings(GtkMenuItem * menuitem,
    1.42 +                                      gpointer user_data);
    1.43 +
    1.44 +/*
    1.45 + * main box from button box separator
    1.46 + */
    1.47 +static GtkWidget *main_vseparator = NULL;
    1.48 +
    1.49 +GdkPixbuf      *icon_sports,
    1.50 +               *icon_news,
    1.51 +               *icon_movies,
    1.52 +               *icon_shows,
    1.53 +               *icon_default;
    1.54 +
    1.55 +#ifndef MAEMO_PLATFORM
    1.56 +/*
    1.57 + * FIXME: 
    1.58 + */
    1.59 +static MMythUi *popup_mmyth_ui;
    1.60 +#endif
    1.61 +
    1.62 +MMythUi        *
    1.63 +mmyth_ui_initialize(
    1.64 +#ifdef MAEMO_PLATFORM
    1.65 +                       HildonProgram * program,
    1.66 +#endif
    1.67 +                       GtkWidget * main_window)
    1.68 +{
    1.69 +    MMythUi        *mmyth_ui;
    1.70 +
    1.71 +    mmyth_ui = g_new0(MMythUi, 1);
    1.72 +
    1.73 +    mmyth_ui->backend_info =
    1.74 +        gmyth_backend_info_new_full("localhost", "mythtv", "mythtv",
    1.75 +                                    "mythconverg", 6543);
    1.76 +
    1.77 +    mmyth_ui->main_window = main_window;
    1.78 +    mmyth_ui->videow = NULL;
    1.79 +    mmyth_ui->mmyth_recordui = NULL;
    1.80 +    mmyth_ui->mmyth_schedulerui = NULL;
    1.81 +
    1.82 +    /*
    1.83 +     * Horizontal box that divides the view into control and video area 
    1.84 +     */
    1.85 +    mmyth_ui->main_hbox = gtk_hbox_new(FALSE, 0);
    1.86 +    gtk_widget_show(mmyth_ui->main_hbox);
    1.87 +    g_object_ref(mmyth_ui->main_hbox);
    1.88 +
    1.89 +    main_bg_color.red = 65000;
    1.90 +    main_bg_color.green = 65000;
    1.91 +    main_bg_color.blue = 65000;
    1.92 +
    1.93 +
    1.94 +#ifndef MAEMO_PLATFORM
    1.95 +    /*
    1.96 +     * Popup menu 
    1.97 +     */
    1.98 +    popup_mmyth_ui = mmyth_ui;
    1.99 +    g_signal_connect(G_OBJECT(mmyth_ui->main_hbox), "event",
   1.100 +                     G_CALLBACK(button_press_handler),
   1.101 +                     G_OBJECT(mmyth_ui->main_hbox));
   1.102 +
   1.103 +#else                           // #ifdef MAEMO
   1.104 +
   1.105 +    mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
   1.106 +    hildon_program_set_common_menu(program, mmyth_ui->main_menu);
   1.107 +
   1.108 +    mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
   1.109 +    gtk_widget_set_size_request(GTK_WIDGET(mmyth_ui->menu_setup), 150, 40);
   1.110 +    gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
   1.111 +
   1.112 +    g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate",
   1.113 +                     G_CALLBACK(cb_menu_item_settings), mmyth_ui);
   1.114 +
   1.115 +    gtk_widget_show_all(GTK_WIDGET(mmyth_ui->main_menu));
   1.116 +#endif
   1.117 +
   1.118 +    // Main widget is mmyth_ui->main_hbox
   1.119 +    mmyth_ui->main_uicommon = create_main_view(mmyth_ui);
   1.120 +
   1.121 +    gtk_container_add(GTK_CONTAINER(mmyth_ui->main_window),
   1.122 +                      mmyth_ui->main_hbox);
   1.123 +
   1.124 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
   1.125 +
   1.126 +    return mmyth_ui;
   1.127 +}
   1.128 +
   1.129 +void
   1.130 +mmyth_ui_finalize(MMythUi * mmyth_ui)
   1.131 +{
   1.132 +    if (mmyth_ui != NULL) {
   1.133 +        if (mmyth_ui->main_uicommon)
   1.134 +            mmyth_uicommon_free(mmyth_ui->main_uicommon);
   1.135 +        if (mmyth_ui->video_uicommon)
   1.136 +            mmyth_uicommon_free(mmyth_ui->video_uicommon);
   1.137 +        if (mmyth_ui->epg_grid_uicommon)
   1.138 +            mmyth_uicommon_free(mmyth_ui->epg_grid_uicommon);
   1.139 +        if (mmyth_ui->record_uicommon)
   1.140 +            mmyth_uicommon_free(mmyth_ui->record_uicommon);
   1.141 +        if (mmyth_ui->schedule_uicommon)
   1.142 +            mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
   1.143 +
   1.144 +        g_free(mmyth_ui);
   1.145 +    }
   1.146 +}
   1.147 +
   1.148 +void
   1.149 +mmyth_ui_set_widget(MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
   1.150 +{
   1.151 +    if (new_uicommon == NULL) {
   1.152 +        g_warning("MMythUI setting a NULL UI_Common as current display\n");
   1.153 +        return;
   1.154 +    }
   1.155 +
   1.156 +    if (mmyth_ui->current_uicommon) {
   1.157 +        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
   1.158 +            gtk_widget_hide(mmyth_ui->current_uicommon->main_widget);
   1.159 +            gtk_widget_hide(mmyth_ui->videow);
   1.160 +        } else {
   1.161 +            gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
   1.162 +                                 mmyth_ui->current_uicommon->main_widget);
   1.163 +        }
   1.164 +
   1.165 +        gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
   1.166 +                             mmyth_ui->current_uicommon->event_box);
   1.167 +        gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
   1.168 +                             main_vseparator);
   1.169 +
   1.170 +    }
   1.171 +
   1.172 +    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
   1.173 +        // gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
   1.174 +        gtk_widget_show(mmyth_ui->video_alignment);
   1.175 +        gtk_widget_show(mmyth_ui->videow);
   1.176 +    } else {
   1.177 +        /*
   1.178 +         * FIXME: Fst call is NULL when mmyth_player_init fails 
   1.179 +         */
   1.180 +        if (mmyth_ui->video_alignment != NULL)
   1.181 +            gtk_widget_hide(mmyth_ui->video_alignment);
   1.182 +        /*
   1.183 +         * FIXME: Fst call is NULL when mmyth_player_init fails 
   1.184 +         */
   1.185 +        if (mmyth_ui->videow != NULL)
   1.186 +            gtk_widget_hide(mmyth_ui->videow);
   1.187 +
   1.188 +        gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
   1.189 +                           new_uicommon->main_widget, TRUE, TRUE, 0);
   1.190 +    }
   1.191 +
   1.192 +    if (main_vseparator == NULL) {
   1.193 +        /*
   1.194 +         * FIXME: should free this variable
   1.195 +         */
   1.196 +        main_vseparator = gtk_vseparator_new();
   1.197 +        g_object_ref(main_vseparator);
   1.198 +    }
   1.199 +    gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
   1.200 +                       main_vseparator, FALSE, FALSE, 0);
   1.201 +    gtk_widget_show(main_vseparator);
   1.202 +
   1.203 +    gtk_box_pack_end(GTK_BOX(mmyth_ui->main_hbox), new_uicommon->event_box,
   1.204 +                     FALSE, FALSE, 0);
   1.205 +
   1.206 +    mmyth_ui->current_uicommon = new_uicommon;
   1.207 +
   1.208 +}
   1.209 +
   1.210 +/*
   1.211 + * The close callback is the same for all windows
   1.212 + */
   1.213 +static void
   1.214 +cb_not_impl_button(GtkButton * button, gpointer user_data)
   1.215 +{
   1.216 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.217 +
   1.218 +    GtkWidget      *msg_dialog =
   1.219 +        gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
   1.220 +                               GTK_DIALOG_MODAL |
   1.221 +                               GTK_DIALOG_DESTROY_WITH_PARENT,
   1.222 +                               GTK_MESSAGE_INFO,
   1.223 +                               GTK_BUTTONS_OK,
   1.224 +                               "Feature not implemented");
   1.225 +    gtk_widget_set_size_request(msg_dialog, 350, 120);
   1.226 +
   1.227 +    gtk_dialog_run(GTK_DIALOG(msg_dialog));
   1.228 +
   1.229 +    gtk_widget_destroy(GTK_WIDGET(msg_dialog));
   1.230 +}
   1.231 +
   1.232 +/******************************************************************************
   1.233 + *                        POPUP MENU WIDGET METHODS                           *
   1.234 + *****************************************************************************/
   1.235 +
   1.236 +static void
   1.237 +cb_menu_item_settings(GtkMenuItem * menuitem, gpointer user_data)
   1.238 +{
   1.239 +
   1.240 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.241 +
   1.242 +    if (mmyth_uisettings_run(GTK_WINDOW(mmyth_ui->main_window))) {
   1.243 +        // If user changes the settings, we restart the context
   1.244 +        g_debug("[%s] Restarting mmyth_context to new settings",
   1.245 +                __FUNCTION__);
   1.246 +        // gmyth_context_initialize();
   1.247 +    }
   1.248 +}
   1.249 +
   1.250 +#ifndef MAEMO_PLATFORM
   1.251 +
   1.252 +static void
   1.253 +detacher(GtkWidget * attach_widget, GtkMenu * menu)
   1.254 +{
   1.255 +
   1.256 +}
   1.257 +
   1.258 +static void
   1.259 +do_popup_menu(GtkWidget * my_widget, GdkEventButton * event)
   1.260 +{
   1.261 +    GtkWidget      *popup;
   1.262 +
   1.263 +    int             button,
   1.264 +                    event_time;
   1.265 +
   1.266 +    GtkWidget      *item_general;
   1.267 +    GtkWidget      *image;
   1.268 +
   1.269 +    popup = gtk_menu_new();
   1.270 +
   1.271 +    item_general = gtk_image_menu_item_new_with_mnemonic("Setup");
   1.272 +    gtk_widget_show(item_general);
   1.273 +    gtk_container_add(GTK_CONTAINER(popup), item_general);
   1.274 +
   1.275 +    image = gtk_image_new_from_stock("gtk-edit", GTK_ICON_SIZE_MENU);
   1.276 +    gtk_widget_show(image);
   1.277 +    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item_general),
   1.278 +                                  image);
   1.279 +
   1.280 +    g_signal_connect(G_OBJECT(item_general), "activate",
   1.281 +                     G_CALLBACK(cb_menu_item_settings), popup_mmyth_ui);
   1.282 +
   1.283 +    if (event) {
   1.284 +        button = event->button;
   1.285 +        event_time = event->time;
   1.286 +    } else {
   1.287 +        button = 0;
   1.288 +        event_time = gtk_get_current_event_time();
   1.289 +    }
   1.290 +
   1.291 +    gtk_menu_attach_to_widget(GTK_MENU(popup), my_widget, detacher);
   1.292 +    gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
   1.293 +                   button, event_time);
   1.294 +    gtk_widget_show_all(popup);
   1.295 +}
   1.296 +
   1.297 +/*
   1.298 + * Respond to a button-press by posting a menu passed in as widget. Note
   1.299 + * that the "widget" argument is the menu being posted, NOT the button
   1.300 + * that was pressed. 
   1.301 + */
   1.302 +static          gint
   1.303 +button_press_handler(GtkWidget * widget, GdkEvent * event)
   1.304 +{
   1.305 +
   1.306 +    if (event->type == GDK_BUTTON_PRESS) {
   1.307 +        GdkEventButton *bevent = (GdkEventButton *) event;
   1.308 +        /*
   1.309 +         * Ignore double-clicks and triple-clicks 
   1.310 +         */
   1.311 +        if (bevent->button == 3) {
   1.312 +            do_popup_menu(widget, bevent);
   1.313 +            return TRUE;
   1.314 +        }
   1.315 +    }
   1.316 +
   1.317 +    /*
   1.318 +     * Tell calling code that we have not handled this event; pass it on. 
   1.319 +     */
   1.320 +    return FALSE;
   1.321 +}
   1.322 +#endif
   1.323 +
   1.324 +/******************************************************************************
   1.325 + *                          MAIN APP VIEW METHODS                             *
   1.326 + *****************************************************************************/
   1.327 +
   1.328 +static void
   1.329 +cb_close_button(GtkButton * button, gpointer user_data)
   1.330 +{
   1.331 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.332 +
   1.333 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
   1.334 +}
   1.335 +
   1.336 +static void
   1.337 +cb_watch_tv_button(GtkButton * button, gpointer user_data)
   1.338 +{
   1.339 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.340 +    gboolean        res = FALSE;
   1.341 +
   1.342 +    if (!(mmyth_ui->video_uicommon))
   1.343 +        mmyth_ui->video_uicommon = create_video_view(mmyth_ui);
   1.344 +
   1.345 +    // Creates the tv player that will retrieve the mythtv content, decode 
   1.346 +    // and show it
   1.347 +    mmyth_ui->tvplayer = mmyth_tvplayer_new();
   1.348 +    /*
   1.349 +     * choose here if this is a LiveTV session 
   1.350 +     */
   1.351 +    mmyth_ui->tvplayer->is_livetv = TRUE;
   1.352 +
   1.353 +    res =
   1.354 +        mmyth_tvplayer_initialize(mmyth_ui->tvplayer,
   1.355 +                                  mmyth_ui->backend_info);
   1.356 +
   1.357 +    if (!res) {
   1.358 +        g_warning("[%s] Could not initialize tvplayer", __FUNCTION__);
   1.359 +
   1.360 +        g_object_unref(mmyth_ui->tvplayer);
   1.361 +        mmyth_ui->tvplayer = NULL;
   1.362 +
   1.363 +        GtkWidget      *dialog =
   1.364 +            gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
   1.365 +                                   GTK_DIALOG_DESTROY_WITH_PARENT,
   1.366 +                                   GTK_MESSAGE_ERROR,
   1.367 +                                   GTK_BUTTONS_CLOSE,
   1.368 +                                   "MMyth found errors while starting TV Player, please check "
   1.369 +                                   "the GStreamer installation");
   1.370 +
   1.371 +        gtk_dialog_run(GTK_DIALOG(dialog));
   1.372 +        gtk_widget_destroy(dialog);
   1.373 +
   1.374 +        return;
   1.375 +    }
   1.376 +    // res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
   1.377 +    // 
   1.378 +    if (mmyth_ui && mmyth_ui->tvplayer && res) {
   1.379 +        mmyth_tvplayer_set_widget(mmyth_ui->tvplayer, mmyth_ui->videow);
   1.380 +        mmyth_tvplayer_start_playing(mmyth_ui->tvplayer);
   1.381 +    } else {
   1.382 +        // TODO: Show Alert with error description!
   1.383 +        g_warning("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
   1.384 +        g_object_unref(mmyth_ui->tvplayer);
   1.385 +        mmyth_ui->tvplayer = NULL;
   1.386 +        // FIXME: Show the exact error that happened
   1.387 +        GtkWidget      *dialog =
   1.388 +            gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
   1.389 +                                   GTK_DIALOG_DESTROY_WITH_PARENT,
   1.390 +                                   GTK_MESSAGE_ERROR,
   1.391 +                                   GTK_BUTTONS_CLOSE,
   1.392 +                                   "Error while starting TV Player, please check if the backend"
   1.393 +                                   " is running properly and a tv card is available!");
   1.394 +        gtk_dialog_run(GTK_DIALOG(dialog));
   1.395 +        gtk_widget_destroy(dialog);
   1.396 +        return;
   1.397 +    }
   1.398 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->video_uicommon);
   1.399 +
   1.400 +}
   1.401 +
   1.402 +static void
   1.403 +cb_epg_button(GtkButton * button, gpointer user_data)
   1.404 +{
   1.405 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.406 +
   1.407 +    if (!(mmyth_ui->epg_grid_uicommon))
   1.408 +        mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
   1.409 +
   1.410 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->epg_grid_uicommon);
   1.411 +}
   1.412 +
   1.413 +static MMythUiCommon *
   1.414 +create_main_view(MMythUi * mmyth_ui)
   1.415 +{
   1.416 +    MMythUiCommon  *ui_common;
   1.417 +    GtkWidget      *main_widget;
   1.418 +    GtkWidget      *image;
   1.419 +
   1.420 +    g_debug("Creating Main UI Common");
   1.421 +
   1.422 +    // FIXME: file path
   1.423 +#ifdef MMYTH_DEV
   1.424 +    image = gtk_image_new_from_file("../pixmaps/mmyth_logo.png");
   1.425 +#else
   1.426 +    image = gtk_image_new_from_file(PIX_DIR "mmyth_logo.png");
   1.427 +#endif
   1.428 +
   1.429 +    main_widget = gtk_event_box_new();
   1.430 +
   1.431 +    gtk_container_add(GTK_CONTAINER(main_widget), image);
   1.432 +
   1.433 +
   1.434 +    gtk_widget_show_all(main_widget);
   1.435 +    g_object_ref(main_widget);
   1.436 +
   1.437 +    ui_common = mmyth_uicommon_new(main_widget,
   1.438 +                                   "Watch TV", "EPG", "Recording");
   1.439 +
   1.440 +    /*
   1.441 +     * Button signals 
   1.442 +     */
   1.443 +    // FIXME
   1.444 +    g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.445 +                     G_CALLBACK(cb_watch_tv_button), mmyth_ui);
   1.446 +    g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
   1.447 +                     G_CALLBACK(cb_epg_button), mmyth_ui);
   1.448 +    g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
   1.449 +                     G_CALLBACK(cb_record_button), mmyth_ui);
   1.450 +
   1.451 +    return ui_common;
   1.452 +
   1.453 +}
   1.454 +
   1.455 +/******************************************************************************
   1.456 + *                         epg GRID VIEW METHODS                              *
   1.457 + *****************************************************************************/
   1.458 +
   1.459 +static MMythUiCommon *
   1.460 +create_epg_grid_view(MMythUi * mmyth_ui)
   1.461 +{
   1.462 +    MMythUiCommon  *ui_common;
   1.463 +
   1.464 +    g_debug("Creating EPG Grid UI Common");
   1.465 +
   1.466 +    GtkWidget      *epg_grid_view =
   1.467 +        GTK_WIDGET(epg_grid_view_new(mmyth_ui));
   1.468 +
   1.469 +    ui_common = mmyth_uicommon_new(epg_grid_view,
   1.470 +                                   "Play", "Record", "Close");
   1.471 +
   1.472 +    /*
   1.473 +     * Button signals 
   1.474 +     */
   1.475 +    g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.476 +                     G_CALLBACK(cb_not_impl_button), mmyth_ui);
   1.477 +    g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
   1.478 +                     G_CALLBACK(cb_record_button), mmyth_ui);
   1.479 +    g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
   1.480 +                     G_CALLBACK(cb_close_button), mmyth_ui);
   1.481 +
   1.482 +    return ui_common;
   1.483 +}
   1.484 +/******************************************************************************
   1.485 + *                         SCHEDULE VIEW METHODS                                *
   1.486 + ******************************************************************************/
   1.487 +
   1.488 +static void
   1.489 +cb_save_new_schedule(GtkButton * button, gpointer user_data)
   1.490 +{
   1.491 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.492 +
   1.493 +    if (!(mmyth_ui->schedule_uicommon))
   1.494 +        mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
   1.495 +
   1.496 +    mmyth_schedulerui_save(mmyth_ui->mmyth_schedulerui);
   1.497 +
   1.498 +    mmyth_recordui_reload_schedule(mmyth_ui->mmyth_recordui);
   1.499 +
   1.500 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->record_uicommon);
   1.501 +
   1.502 +}
   1.503 +
   1.504 +static void
   1.505 +cb_edit_scheduled(GtkTreeView * tree_view, GtkTreePath * path,
   1.506 +                  GtkTreeViewColumn * column, gpointer user_data)
   1.507 +{
   1.508 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.509 +    GtkTreeSelection *selection;
   1.510 +    GtkTreeModel   *list_store;
   1.511 +    GtkTreeIter     iter;
   1.512 +    int             index;
   1.513 +    // gint new_row = 0, record_id = 0;
   1.514 +    ScheduleInfo   *schedule_info;
   1.515 +    GList          *schedule_list;
   1.516 +    // GtkTreeIter iter;
   1.517 +    gint            res;
   1.518 +
   1.519 +    // gtk_tree_store_clear(recordui->sch_tree_store); 
   1.520 +
   1.521 +    res =
   1.522 +        gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->
   1.523 +                                          scheduler, &(schedule_list));
   1.524 +    if (res < 0) {
   1.525 +        g_warning
   1.526 +            ("[%s] Retrieved NULL list of scheduled data from database",
   1.527 +             __FUNCTION__);
   1.528 +        // return FALSE;
   1.529 +    }
   1.530 +    printf("\nX %d", res);
   1.531 +    fflush(stdout);
   1.532 +
   1.533 +    selection =
   1.534 +        gtk_tree_view_get_selection(GTK_TREE_VIEW
   1.535 +                                    (mmyth_ui->mmyth_recordui->
   1.536 +                                     sch_treeview));
   1.537 +
   1.538 +    gtk_tree_selection_get_selected(selection, &list_store, &iter);
   1.539 +    gtk_tree_model_get(list_store, &iter, 4, &index, -1);
   1.540 +
   1.541 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->schedule_uicommon);
   1.542 +
   1.543 +    if (!(mmyth_ui->schedule_uicommon))
   1.544 +        mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
   1.545 +
   1.546 +    schedule_list =
   1.547 +        g_list_nth(schedule_list,
   1.548 +                   g_ascii_strtoull(gtk_tree_path_to_string(path), NULL,
   1.549 +                                    10));
   1.550 +    schedule_info = (ScheduleInfo *) schedule_list->data;
   1.551 +
   1.552 +    printf("\nstarttime: %ld", schedule_info->start_time->tv_sec);
   1.553 +    fflush(stdout);
   1.554 +}
   1.555 +
   1.556 +static MMythUiCommon *
   1.557 +create_schedule_view(MMythUi * mmyth_ui)
   1.558 +{
   1.559 +    MMythUiCommon  *ui_common;
   1.560 +    GtkWidget      *schedule_widget;
   1.561 +
   1.562 +    g_debug("Creating Schedule UI Common");
   1.563 +
   1.564 +    mmyth_ui->mmyth_schedulerui =
   1.565 +        mmyth_schedulerui_new(mmyth_ui->backend_info);
   1.566 +    if (mmyth_ui->mmyth_schedulerui == NULL) {
   1.567 +        g_warning("[%s] Error while creating scheduler ui", __FUNCTION__);
   1.568 +        return NULL;
   1.569 +    }
   1.570 +
   1.571 +    schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
   1.572 +
   1.573 +    gtk_widget_show_all(schedule_widget);
   1.574 +    g_object_ref(schedule_widget);
   1.575 +
   1.576 +    ui_common = mmyth_uicommon_new(schedule_widget,
   1.577 +                                   "Save", "Clear", "Cancel");
   1.578 +
   1.579 +    /*
   1.580 +     * Button signals 
   1.581 +     */
   1.582 +    g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.583 +                     G_CALLBACK(cb_save_new_schedule), mmyth_ui);
   1.584 +    g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
   1.585 +                     G_CALLBACK(cb_not_impl_button), mmyth_ui);
   1.586 +    g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
   1.587 +                     G_CALLBACK(cb_record_button), mmyth_ui);
   1.588 +
   1.589 +    return ui_common;
   1.590 +}
   1.591 +/******************************************************************************
   1.592 + *                         RECORD VIEW METHODS                                *
   1.593 + ******************************************************************************/
   1.594 +static void
   1.595 +cb_record_button(GtkButton * button, gpointer user_data)
   1.596 +{
   1.597 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.598 +
   1.599 +    if (!(mmyth_ui->record_uicommon)) {
   1.600 +        mmyth_ui->record_uicommon = create_record_view(mmyth_ui);
   1.601 +        mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
   1.602 +    }
   1.603 +
   1.604 +    mmyth_recordui_reload_all(mmyth_ui->mmyth_recordui);
   1.605 +
   1.606 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->record_uicommon);
   1.607 +
   1.608 +}
   1.609 +
   1.610 +static void
   1.611 +cb_record_close_button(GtkButton * button, gpointer user_data)
   1.612 +{
   1.613 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.614 +
   1.615 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
   1.616 +
   1.617 +    mmyth_recordui_free(mmyth_ui->mmyth_recordui);
   1.618 +
   1.619 +    if (mmyth_ui->record_uicommon) {
   1.620 +        gtk_widget_destroy(mmyth_ui->record_uicommon->main_widget);
   1.621 +        mmyth_uicommon_free(mmyth_ui->record_uicommon);
   1.622 +        mmyth_ui->record_uicommon = NULL;
   1.623 +    }
   1.624 +
   1.625 +    if (mmyth_ui->schedule_uicommon) {
   1.626 +        // mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
   1.627 +    }
   1.628 +}
   1.629 +
   1.630 +
   1.631 +
   1.632 +
   1.633 +static void
   1.634 +play_selected_recorded(gpointer user_data)
   1.635 +{
   1.636 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.637 +    gboolean        res = FALSE;
   1.638 +
   1.639 +    gchar          *path =
   1.640 +        mmyth_recordui_get_selected_recorded(mmyth_ui->mmyth_recordui);
   1.641 +
   1.642 +    if (path == NULL) {
   1.643 +        // This should never happens. Play button is just activated when
   1.644 +        // a recording is selected.
   1.645 +        g_warning
   1.646 +            ("[%s] Play button pressed while none recorded is selected",
   1.647 +             __FUNCTION__);
   1.648 +        return;
   1.649 +    }
   1.650 +
   1.651 +    if (!(mmyth_ui->video_uicommon))
   1.652 +        mmyth_ui->video_uicommon = create_video_view(mmyth_ui);
   1.653 +
   1.654 +    // Creates the tv player that will retrieve the mythtv content, decode 
   1.655 +    // and show it
   1.656 +    mmyth_ui->tvplayer = mmyth_tvplayer_new();
   1.657 +    g_debug("[%s] New TV Player created: %d\n", __FUNCTION__,
   1.658 +            (int) (mmyth_ui->tvplayer));
   1.659 +    res =
   1.660 +        mmyth_tvplayer_initialize(mmyth_ui->tvplayer,
   1.661 +                                  mmyth_ui->backend_info);
   1.662 +    if (!res) {
   1.663 +        g_warning("[%s] Could not initialize tvplayer", __FUNCTION__);
   1.664 +
   1.665 +        g_object_unref(mmyth_ui->tvplayer);
   1.666 +        mmyth_ui->tvplayer = NULL;
   1.667 +
   1.668 +        GtkWidget      *dialog =
   1.669 +            gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
   1.670 +                                   GTK_DIALOG_DESTROY_WITH_PARENT,
   1.671 +                                   GTK_MESSAGE_ERROR,
   1.672 +                                   GTK_BUTTONS_CLOSE,
   1.673 +                                   "MMyth found errors while starting TV Player, please check "
   1.674 +                                   "the GStreamer installation");
   1.675 +
   1.676 +        gtk_dialog_run(GTK_DIALOG(dialog));
   1.677 +        gtk_widget_destroy(dialog);
   1.678 +
   1.679 +        return;
   1.680 +    }
   1.681 +
   1.682 +    res = mmyth_tvplayer_record_setup(mmyth_ui->tvplayer, path);
   1.683 +
   1.684 +    if (mmyth_ui && mmyth_ui->tvplayer && res) {
   1.685 +        mmyth_tvplayer_set_widget(mmyth_ui->tvplayer, mmyth_ui->videow);
   1.686 +        mmyth_tvplayer_start_playing(mmyth_ui->tvplayer);
   1.687 +    } else {
   1.688 +        // TODO: Show Alert with error description!
   1.689 +        g_warning("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
   1.690 +        g_object_unref(mmyth_ui->tvplayer);
   1.691 +        mmyth_ui->tvplayer = NULL;
   1.692 +        // FIXME: Show the exact error that happened
   1.693 +        GtkWidget      *dialog =
   1.694 +            gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
   1.695 +                                   GTK_DIALOG_DESTROY_WITH_PARENT,
   1.696 +                                   GTK_MESSAGE_ERROR,
   1.697 +                                   GTK_BUTTONS_CLOSE,
   1.698 +                                   "Error while starting TV Player, please check if the backend"
   1.699 +                                   " is running properly and a tv card is available!");
   1.700 +        gtk_dialog_run(GTK_DIALOG(dialog));
   1.701 +        gtk_widget_destroy(dialog);
   1.702 +        return;
   1.703 +    }
   1.704 +
   1.705 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->video_uicommon);
   1.706 +}
   1.707 +
   1.708 +static void
   1.709 +cb_play_clicked_recorded(GtkTreeView * tree_view, GtkTreePath * path,
   1.710 +                         GtkTreeViewColumn * column, gpointer user_data)
   1.711 +{
   1.712 +    play_selected_recorded(user_data);
   1.713 +}
   1.714 +
   1.715 +static void
   1.716 +cb_play_selected(GtkButton * button, gpointer user_data)
   1.717 +{
   1.718 +    play_selected_recorded(user_data);
   1.719 +}
   1.720 +
   1.721 +static void
   1.722 +cb_schedule_button(GtkButton * button, gpointer user_data)
   1.723 +{
   1.724 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.725 +
   1.726 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->schedule_uicommon);
   1.727 +}
   1.728 +
   1.729 +void
   1.730 +cb_switch_page(GtkNotebook * notebook, GtkNotebookPage * page,
   1.731 +               guint page_num, gpointer user_data)
   1.732 +{
   1.733 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.734 +    MMythUiCommon  *ui_common;
   1.735 +
   1.736 +    assert(mmyth_ui);
   1.737 +    assert(mmyth_ui->record_uicommon);
   1.738 +
   1.739 +    ui_common = mmyth_ui->record_uicommon;
   1.740 +
   1.741 +    if (page_num == 0) {        // Switched to Schedule list
   1.742 +        gtk_button_set_label(GTK_BUTTON(ui_common->button1), "New");
   1.743 +        g_signal_handlers_disconnect_by_func(G_OBJECT(ui_common->button1),
   1.744 +                                             G_CALLBACK(cb_play_selected),
   1.745 +                                             mmyth_ui);
   1.746 +        g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.747 +                         G_CALLBACK(cb_schedule_button), mmyth_ui);
   1.748 +    } else if (page_num == 1) {
   1.749 +        gtk_button_set_label(GTK_BUTTON(ui_common->button1), "Play");
   1.750 +        g_signal_handlers_disconnect_by_func(G_OBJECT(ui_common->button1),
   1.751 +                                             G_CALLBACK
   1.752 +                                             (cb_schedule_button),
   1.753 +                                             mmyth_ui);
   1.754 +        g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.755 +                         G_CALLBACK(cb_play_selected), mmyth_ui);
   1.756 +    }
   1.757 +}
   1.758 +
   1.759 +
   1.760 +static MMythUiCommon *
   1.761 +create_record_view(MMythUi * mmyth_ui)
   1.762 +{
   1.763 +    MMythUiCommon  *ui_common;
   1.764 +
   1.765 +    g_debug("Creating Record UI Common");
   1.766 +
   1.767 +    mmyth_ui->mmyth_recordui = mmyth_recordui_new(mmyth_ui->backend_info);
   1.768 +
   1.769 +    // FIXME: Change MMythRecordUI to a GtkWidget child and avoid this
   1.770 +    // call!
   1.771 +    gtk_widget_show_all(mmyth_ui->mmyth_recordui->scrolled_window);
   1.772 +
   1.773 +    ui_common =
   1.774 +        mmyth_uicommon_new(mmyth_ui->mmyth_recordui->scrolled_window,
   1.775 +                           "New", "Delete", "<<Back");
   1.776 +    g_object_ref(mmyth_ui->mmyth_recordui->scrolled_window);
   1.777 +
   1.778 +    /*
   1.779 +     * Button signals 
   1.780 +     */
   1.781 +    g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.782 +                     G_CALLBACK(cb_schedule_button), mmyth_ui);
   1.783 +    g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
   1.784 +                     G_CALLBACK(mmyth_recordui_delete_selected),
   1.785 +                     mmyth_ui->mmyth_recordui);
   1.786 +    g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
   1.787 +                     G_CALLBACK(cb_record_close_button), mmyth_ui);
   1.788 +    g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->notebook),
   1.789 +                     "switch-page", G_CALLBACK(cb_switch_page), mmyth_ui);
   1.790 +    g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->rec_treeview),
   1.791 +                     "row-activated", G_CALLBACK(cb_play_clicked_recorded),
   1.792 +                     mmyth_ui);
   1.793 +    g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->sch_treeview),
   1.794 +                     "row-activated", G_CALLBACK(cb_edit_scheduled),
   1.795 +                     mmyth_ui);
   1.796 +    return ui_common;
   1.797 +}
   1.798 +
   1.799 +
   1.800 +/******************************************************************************
   1.801 + *                         GST VIDEO WIDGET METHODS                           *
   1.802 + *****************************************************************************/
   1.803 +
   1.804 +static void
   1.805 +cb_video_close_button(GtkButton * button, gpointer user_data)
   1.806 +{
   1.807 +    MMythUi        *mmyth_ui = (MMythUi *) user_data;
   1.808 +
   1.809 +    g_debug("MMythUI video close button pressed");
   1.810 +
   1.811 +    if (mmyth_ui && mmyth_ui->tvplayer) {
   1.812 +        mmyth_tvplayer_stop_playing(mmyth_ui->tvplayer);
   1.813 +
   1.814 +        g_object_unref(mmyth_ui->tvplayer);
   1.815 +        mmyth_ui->tvplayer = NULL;
   1.816 +    } else {
   1.817 +        g_warning("cb_video_close_button called with NULL pointer\n");
   1.818 +    }
   1.819 +
   1.820 +    mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
   1.821 +}
   1.822 +
   1.823 +
   1.824 +static MMythUiCommon *
   1.825 +create_video_view(MMythUi * mmyth_ui)
   1.826 +{
   1.827 +
   1.828 +    MMythUiCommon  *ui_common;
   1.829 +
   1.830 +    g_debug("Creating Video UI Common");
   1.831 +
   1.832 +    /*
   1.833 +     * Creates widget to be user by MMythTVPlayer to draw the video 
   1.834 +     */
   1.835 +    mmyth_ui->videow = gtk_drawing_area_new();
   1.836 +    // FIXME: Get the widget size from settings
   1.837 +    gtk_widget_set_size_request(mmyth_ui->videow, 300, 240);
   1.838 +
   1.839 +    // mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
   1.840 +
   1.841 +    // Creates an alignment to place the video widget inside
   1.842 +    mmyth_ui->video_alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
   1.843 +    gtk_widget_hide(mmyth_ui->video_alignment);
   1.844 +
   1.845 +    gtk_container_add(GTK_CONTAINER(mmyth_ui->video_alignment),
   1.846 +                      mmyth_ui->videow);
   1.847 +
   1.848 +    /*
   1.849 +     * Add the gst video widget to hbox. It should never be removed. 
   1.850 +     */
   1.851 +    /*
   1.852 +     * FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init
   1.853 +     * fails 
   1.854 +     */
   1.855 +    if ((mmyth_ui->main_hbox != NULL)
   1.856 +        && (mmyth_ui->video_alignment != NULL)) {
   1.857 +        gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
   1.858 +                           mmyth_ui->video_alignment, TRUE, TRUE, 0);
   1.859 +    } else {
   1.860 +        g_warning("[%s] Error while adding video_alignment to main widget",
   1.861 +                  __FUNCTION__);
   1.862 +    }
   1.863 +
   1.864 +    g_object_ref(mmyth_ui->videow);
   1.865 +    g_object_ref(mmyth_ui->video_alignment);
   1.866 +
   1.867 +    ui_common = mmyth_uicommon_new(mmyth_ui->video_alignment,
   1.868 +                                   "  Full\nScreen", "Other\nServices",
   1.869 +                                   "Close");
   1.870 +
   1.871 +
   1.872 +    g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
   1.873 +                     G_CALLBACK(cb_not_impl_button), mmyth_ui);
   1.874 +    g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
   1.875 +                     G_CALLBACK(cb_not_impl_button), mmyth_ui);
   1.876 +    g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
   1.877 +                     G_CALLBACK(cb_video_close_button), mmyth_ui);
   1.878 +
   1.879 +    if (ui_common)
   1.880 +        g_debug("Video UI_Common sucessfull created");
   1.881 +
   1.882 +    return ui_common;
   1.883 +}
   1.884 +
   1.885 +
   1.886 +
   1.887 +GtkWidget      *
   1.888 +mmyth_ui_get_video_widget(MMythUi * mmyth_ui)
   1.889 +{
   1.890 +
   1.891 +    if (mmyth_ui && mmyth_ui->videow) {
   1.892 +
   1.893 +        return mmyth_ui->videow;
   1.894 +    }
   1.895 +
   1.896 +    return NULL;
   1.897 +}