static void
add_header(prop_courier_t *pc, GtkWidget *parent, prop_t *root)
{
  GtkWidget *hbox, *w;
  prop_sub_t *s;


  hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, TRUE, 0);


  /* Artist name */
  w = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
  gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);

  gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 0);

  s = prop_subscribe(0,
		     PROP_TAG_NAME("self", "model", "artist_name"),
		     PROP_TAG_CALLBACK_STRING, gu_subscription_set_label_xl, w,
		     PROP_TAG_COURIER, pc, 
		     PROP_TAG_NAMED_ROOT, root, "self",
		     NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), s);
}
Esempio n. 2
0
static navigator_t *
nav_create(prop_t *prop)
{
  navigator_t *nav = calloc(1, sizeof(navigator_t));
  nav->nav_prop_root = prop;

  TAILQ_INIT(&nav->nav_pages);
  TAILQ_INIT(&nav->nav_history);

  nav->nav_prop_pages       = prop_create(nav->nav_prop_root, "pages");
  nav->nav_prop_curpage     = prop_create(nav->nav_prop_root, "currentpage");
  nav->nav_prop_can_go_back = prop_create(nav->nav_prop_root, "canGoBack");
  nav->nav_prop_can_go_fwd  = prop_create(nav->nav_prop_root, "canGoForward");
  nav->nav_prop_can_go_home = prop_create(nav->nav_prop_root, "canGoHome");
  prop_set_int(nav->nav_prop_can_go_home, 1);

  nav->nav_pc = prop_courier_create_thread(NULL, "navigator");

  nav->nav_eventsink = 
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "eventsink"),
		   PROP_TAG_CALLBACK, nav_eventsink, nav,
		   PROP_TAG_COURIER, nav->nav_pc,
		   PROP_TAG_ROOT, nav->nav_prop_root,
		   NULL);

  nav->nav_dtor_tracker =
    prop_subscribe(PROP_SUB_TRACK_DESTROY,
		   PROP_TAG_CALLBACK, nav_dtor_tracker, nav,
		   PROP_TAG_COURIER, nav->nav_pc,
		   PROP_TAG_ROOT, nav->nav_prop_root,
		   NULL);

  return nav;
}
Esempio n. 3
0
static void
opts_clicked(GtkToolButton *toolbutton, gpointer user_data)
{
  int event_time = gtk_get_current_event_time();
  gu_tab_t *gt = user_data;
  gtk_ui_t *gu = gt->gt_gw->gw_gu;

  dyn_menu_t *dm = calloc(1, sizeof(dyn_menu_t));

  dm->dm_menu = gtk_menu_new();
  gtk_widget_show_all(dm->dm_menu);

  gtk_menu_attach_to_widget(GTK_MENU(dm->dm_menu), GTK_WIDGET(toolbutton), NULL);

  gtk_menu_popup(GTK_MENU(dm->dm_menu), NULL, NULL, NULL, NULL, 
		 0, event_time);

  gu_cloner_init(&dm->dm_nodes, dm, dyn_menu_item_add, dyn_menu_item_del,
		 sizeof(dyn_menu_item_t), gu, GU_CLONER_TRACK_POSITION);

  dm->dm_node_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "currentpage", "model", "options"),
		   PROP_TAG_CALLBACK, gu_cloner_subscription, &dm->dm_nodes,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);

  g_signal_connect(dm->dm_menu, "destroy", G_CALLBACK(dyn_menu_destroyed), dm);
}
static void
add_albums(gu_tab_t *gt, GtkWidget *parent, prop_t *root)
{
  GtkWidget *sbox;
  albumbrowse_t *ab = calloc(1, sizeof(albumbrowse_t));

  ab->gt = gt;

  /* Scrolled window */
  sbox = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sbox),
				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

  gtk_box_pack_start(GTK_BOX(parent), sbox, TRUE, TRUE, 0);


  /* vbox for all albums */
  ab->vbox = gtk_vbox_new(FALSE, 1);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sbox), ab->vbox);

  ab->sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "model", "nodes"),
		   PROP_TAG_CALLBACK, collection_albums, ab,
		   PROP_TAG_COURIER, gt->gt_gw->gw_gu->gu_pc, 
		   PROP_TAG_NAMED_ROOT, root, "self",
		   NULL);

  g_signal_connect(sbox, "destroy", G_CALLBACK(ab_destroy), ab);
}
Esempio n. 5
0
File: gu.c Progetto: Cy-4AH/showtime
gu_tab_t *
gu_tab_create(gu_window_t *gw, int select, prop_t *nav)
{
  gu_tab_t *gt = calloc(1, sizeof(gu_tab_t));
  prop_sub_t *s;
  int idx;

  gt->gt_gw = gw;

  LIST_INSERT_HEAD(&gw->gw_tabs, gt, gt_link);
  gw->gw_current_tab = gt;
  gw->gw_ntabs++;

  gt->gt_nav = nav ?: nav_spawn();
  if(prop_set_parent(gt->gt_nav, prop_get_global()))
    abort();

  gt->gt_vbox = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(gt->gt_vbox);

  gt->gt_notebook = gtk_notebook_new();
  gtk_widget_show(gt->gt_notebook);

  gtk_notebook_set_show_border(GTK_NOTEBOOK(gt->gt_notebook), 0);
  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gt->gt_notebook), 0);
  
  gu_toolbar_add(gt, gt->gt_vbox);
  gtk_container_add(GTK_CONTAINER(gt->gt_vbox), gt->gt_notebook);

  build_tab_header(gt);

  s = prop_subscribe(0,
		     PROP_TAG_NAME("nav", "pages"),
		     PROP_TAG_CALLBACK, gu_nav_pages, gt,
		     PROP_TAG_COURIER, glibcourier,
		     PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		     NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(gt->gt_notebook), s);


  // Add to tab's notebook

  idx = gtk_notebook_append_page(GTK_NOTEBOOK(gw->gw_notebook),
				 gt->gt_vbox, gt->gt_label);

  gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(gw->gw_notebook), 
				   gt->gt_vbox, 1);


  if(select)
    gtk_notebook_set_current_page(GTK_NOTEBOOK(gw->gw_notebook), idx);

  if(gw->gw_ntabs > 1)
    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gw->gw_notebook), 1);
  

  return gt;
}
Esempio n. 6
0
static void
gu_openerror_create(gu_nav_page_t *gnp)
{
    prop_sub_t *s;
    GtkWidget *l;

    gnp->gnp_pageroot = gtk_vbox_new(FALSE, 3);
    gtk_container_add(GTK_CONTAINER(gnp->gnp_pagebin), gnp->gnp_pageroot);

    l = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(l),
                         "<span size=\"x-large\">Unable to open page</span>");
    gtk_box_pack_start(GTK_BOX(gnp->gnp_pageroot), l, FALSE, FALSE, 0);
    gtk_label_set_ellipsize(GTK_LABEL(l), PANGO_ELLIPSIZE_END);



    l = gtk_label_new(NULL);
    gtk_box_pack_start(GTK_BOX(gnp->gnp_pageroot), l, FALSE, FALSE, 0);
    gtk_label_set_ellipsize(GTK_LABEL(l), PANGO_ELLIPSIZE_END);

    s = prop_subscribe(PROP_SUB_DIRECT_UPDATE,
                       PROP_TAG_NAME("self", "url"),
                       PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, l,
                       PROP_TAG_COURIER, glibcourier,
                       PROP_TAG_NAMED_ROOT, gnp->gnp_prop, "self",
                       NULL);
    gu_unsubscribe_on_destroy(GTK_OBJECT(l), s);



    l = gtk_label_new(NULL);
    gtk_box_pack_start(GTK_BOX(gnp->gnp_pageroot), l, FALSE, FALSE, 0);
    gtk_label_set_ellipsize(GTK_LABEL(l), PANGO_ELLIPSIZE_END);

    s = prop_subscribe(PROP_SUB_DIRECT_UPDATE,
                       PROP_TAG_NAME("self", "model", "error"),
                       PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, l,
                       PROP_TAG_COURIER, glibcourier,
                       PROP_TAG_NAMED_ROOT, gnp->gnp_prop, "self",
                       NULL);
    gu_unsubscribe_on_destroy(GTK_OBJECT(l), s);

    gtk_widget_show_all(gnp->gnp_pageroot);
}
Esempio n. 7
0
void
gu_popup_init(gtk_ui_t *gu)
{
  gu->gu_popup_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "popups"),
		   PROP_TAG_CALLBACK, popups_update, gu,
		   PROP_TAG_COURIER, glibcourier,
		   NULL);
}
Esempio n. 8
0
static void
build_tab_header(gu_tab_t *gt)
{
  prop_courier_t *pc = gt->gt_gw->gw_gu->gu_pc;
  GtkWidget *l, *img;
  prop_sub_t *s;

  // Tab header
  gt->gt_label = gtk_hbox_new(FALSE, 0);
  gtk_widget_set_size_request(gt->gt_label, 150, -1);

  img = gtk_image_new();
  gtk_box_pack_start(GTK_BOX(gt->gt_label), img, FALSE, TRUE, 0);

  s = prop_subscribe(PROP_SUB_DIRECT_UPDATE,
		     PROP_TAG_NAME("nav", "currentpage", 
				   "model", "type"),
		     PROP_TAG_CALLBACK_STRING, gu_set_icon_by_type, img,
		     PROP_TAG_COURIER, pc, 
		     PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		     NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(img), s);

  l = gtk_label_new("");
  gtk_box_pack_start(GTK_BOX(gt->gt_label), l, TRUE, TRUE, 0);

  gtk_label_set_ellipsize(GTK_LABEL(l), PANGO_ELLIPSIZE_END);
  gtk_misc_set_alignment(GTK_MISC(l), 0, 0.5);
  gtk_misc_set_padding(GTK_MISC(l), 5, 0);

  s = prop_subscribe(PROP_SUB_DIRECT_UPDATE,
		     PROP_TAG_NAME("nav", "currentpage", 
				   "model", "metadata", "title"),
		     PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, l,
		     PROP_TAG_COURIER, pc,
		     PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		     NULL);
  gu_unsubscribe_on_destroy(GTK_OBJECT(l), s);

  gtk_widget_show_all(gt->gt_label);
}
Esempio n. 9
0
static void
dyn_menu_item_add(gtk_ui_t *gu, dyn_menu_t *dm,
		  prop_t *p, dyn_menu_item_t *dmi, dyn_menu_item_t *before,
		  int position)
{
  dmi->dmi_dm = dm;

  dmi->dmi_prop = prop_ref_inc(p);

  dmi->dmi_type_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("node", "type"),
		   PROP_TAG_CALLBACK_STRING, dmi_set_type, dmi,
		   PROP_TAG_NAMED_ROOT, p, "node",
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);

  dmi->dmi_title_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("node", "metadata", "title"),
		   PROP_TAG_CALLBACK_STRING, dmi_set_title, dmi,
		   PROP_TAG_NAMED_ROOT, p, "node",
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);

  dmi->dmi_enabled_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("node", "enabled"),
		   PROP_TAG_CALLBACK_INT, dmi_set_enabled, dmi,
		   PROP_TAG_NAMED_ROOT, p, "node",
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);

  dmi->dmi_value_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("node", "value"),
		   PROP_TAG_CALLBACK_INT, dmi_set_value, dmi,
		   PROP_TAG_NAMED_ROOT, p, "node",
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);
}
Esempio n. 10
0
static gu_nav_page_t *
gu_nav_page_create(gu_tab_t *gt, prop_t *p)
{
  gu_nav_page_t *gnp = calloc(1, sizeof(gu_nav_page_t));
  gtk_ui_t *gu = gt->gt_gw->gw_gu;

  gnp->gnp_gt = gt;
  gnp->gnp_prop = prop_ref_inc(p);

  gnp->gnp_pagebin = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(gnp->gnp_pagebin);
  gtk_container_set_border_width(GTK_CONTAINER(gnp->gnp_pagebin), 0);

  gtk_notebook_append_page(GTK_NOTEBOOK(gt->gt_notebook), gnp->gnp_pagebin,
			   NULL);

  LIST_INSERT_HEAD(&gt->gt_pages, gnp, gnp_link);

  gnp->gnp_sub_type = 
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "model", "type"),
		   PROP_TAG_CALLBACK_STRING, gu_nav_page_set_type, gnp,
		   PROP_TAG_COURIER, gu->gu_pc, 
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  gnp->gnp_sub_url =
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "url"),
		   PROP_TAG_CALLBACK_STRING, gu_nav_page_set_url, gnp,
		   PROP_TAG_COURIER, gu->gu_pc, 
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  g_signal_connect(gnp->gnp_pagebin, "destroy", G_CALLBACK(gnp_dtor), gnp);
  return gnp;
}
Esempio n. 11
0
void
media_init(void)
{
  media_codec_init();

  hts_mutex_init(&media_mutex);

  media_prop_root    = prop_create(prop_get_global(), "media");
  media_prop_sources = prop_create(media_prop_root, "sources");
  media_prop_current = prop_create(media_prop_root, "current");
  HTS_JOIN(sp, k0)[4] = 0x78;
  prop_subscribe(0,
		 PROP_TAG_NAME("media", "eventSink"),
		 PROP_TAG_CALLBACK, media_global_eventsink, NULL,
		 PROP_TAG_MUTEX, &media_mutex,
		 PROP_TAG_ROOT, media_prop_root,
		 NULL);

}
Esempio n. 12
0
/**
 * Linux main
 */
int
main(int argc, char **argv)
{
    gconf.binary = argv[0];

    posix_init();

    XInitThreads();
    hts_mutex_init(&gdk_mutex);

    g_thread_init(NULL);
    gdk_threads_set_lock_functions(gdk_obtain, gdk_release);

    gdk_threads_init();
    gdk_threads_enter();
    gtk_init(&argc, &argv);

    parse_opts(argc, argv);

    linux_init();

    main_init();

    if(gconf.ui && !strcmp(gconf.ui, "gu"))
        ui_wanted = &ui_gu;

    glibcourier = glib_courier_create(g_main_context_default());

    prop_subscribe(0,
                   PROP_TAG_NAME("global", "eventSink"),
                   PROP_TAG_CALLBACK_EVENT, linux_global_eventsink, NULL,
                   PROP_TAG_COURIER, glibcourier,
                   NULL);

    add_xdg_paths();

    mainloop();

    main_fini();

    arch_exit();
}
Esempio n. 13
0
GtkWidget *
gu_statusbar_add(gu_window_t *gw, GtkWidget *parent)
{

  statusbar_t *sb = calloc(1, sizeof(statusbar_t));
  
  sb->bar = gtk_statusbar_new();
  gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(sb->bar), TRUE);
  gtk_box_pack_start(GTK_BOX(parent), sb->bar, FALSE, TRUE, 0);

  sb->ctxid =  gtk_statusbar_get_context_id(GTK_STATUSBAR(sb->bar),
					    "notifications");

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "notifications", "nodes"),
		 PROP_TAG_CALLBACK, notifications_update, sb,
		 PROP_TAG_COURIER, gw->gw_gu->gu_pc, 
		 NULL);
  return sb->bar;
}
Esempio n. 14
0
void
gu_settings_create(gu_nav_page_t *gnp)
{
  GtkWidget *vbox;
  gu_tab_t *gt = gnp->gnp_gt;
  gtk_ui_t *gu = gt->gt_gw->gw_gu;

  settinglist_t *sl = calloc(1, sizeof(settinglist_t));
  sl->sl_gt = gnp->gnp_gt;

  /* Scrolled window */
  gnp->gnp_pageroot = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gnp->gnp_pageroot),
				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

  /* Vbox */
  vbox = gtk_vbox_new(FALSE, 1);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(gnp->gnp_pageroot),
					vbox);

  sl->sl_box = vbox;


  gu_cloner_init(&sl->sl_nodes, sl, source_add, source_del, sizeof(setting_t),
		 gu, GU_CLONER_TRACK_POSITION);

  sl->sl_node_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("page", "model", "nodes"),
		   PROP_TAG_CALLBACK, gu_cloner_subscription, &sl->sl_nodes,
		   PROP_TAG_ROOT, gnp->gnp_prop, 
		   PROP_TAG_COURIER, gu->gu_pc,
		   NULL);


  g_signal_connect(GTK_OBJECT(gnp->gnp_pageroot), 
		   "destroy", G_CALLBACK(settinglist_destroy), sl);

  gtk_container_add(GTK_CONTAINER(gnp->gnp_pagebin), gnp->gnp_pageroot);
  gtk_widget_show_all(gnp->gnp_pageroot);
}
Esempio n. 15
0
static void
init_autostandby(void)
{
    htsmsg_t *store = htsmsg_store_load("runcontrol");
    if(store == NULL)
        store = htsmsg_create_map();

    settings_create_int(settings_general, "autostandby", _p("Automatic standby"),
                        0, store, 0, 60, 5, set_autostandby, NULL,
                        SETTINGS_INITIAL_UPDATE, " min", NULL,
                        runcontrol_save_settings, NULL);

    last_activity = showtime_get_ts();

    prop_subscribe(0,
                   PROP_TAG_NAME("global", "media", "current", "playstatus"),
                   PROP_TAG_CALLBACK_STRING, current_media_playstatus, NULL,
                   NULL);

    callout_arm(&autostandby_timer, check_autostandby, NULL, 1);
}
Esempio n. 16
0
void
gu_home_create(gu_nav_page_t *gnp)
{
  GtkWidget *vbox;
  gu_tab_t *gt = gnp->gnp_gt;
  gtk_ui_t *gu = gt->gt_gw->gw_gu;

  home_t *h = calloc(1, sizeof(home_t));
  h->h_gt = gnp->gnp_gt;

  /* Scrolled window */
  gnp->gnp_pageroot = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gnp->gnp_pageroot),
				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

  /* Vbox */
  vbox = gtk_vbox_new(FALSE, 1);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(gnp->gnp_pageroot),
					vbox);

  h->h_sourcebox = vbox;


  gu_cloner_init(&h->h_sources, h, source_add, source_del, sizeof(source_t),
		 gu, GU_CLONER_TRACK_POSITION);

  h->h_src_sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "services", "enabled"),
		   PROP_TAG_CALLBACK, gu_cloner_subscription, &h->h_sources,
		   PROP_TAG_COURIER, glibcourier,
		   NULL);


  g_signal_connect(GTK_OBJECT(gnp->gnp_pageroot), 
		   "destroy", G_CALLBACK(home_destroy), h);

  gtk_container_add(GTK_CONTAINER(gnp->gnp_pagebin), gnp->gnp_pageroot);
  gtk_widget_show_all(gnp->gnp_pageroot);
}
Esempio n. 17
0
static void
init_sleeptimer(prop_t *rc)
{
  const int maxtime = 180;
  sleeptime_prop = prop_create(rc, "sleepTime");
  prop_set_int(sleeptime_prop, 60);
  prop_set_int_clipping_range(sleeptime_prop, 0, maxtime);

  prop_set(rc, "sleepTimeMax",  PROP_SET_INT, maxtime);
  prop_set(rc, "sleepTimeStep", PROP_SET_INT, 5);

  sleeptime_sub =
    prop_subscribe(0,
                   PROP_TAG_CALLBACK_INT, update_sleeptime, NULL,
                   PROP_TAG_ROOT, sleeptime_prop,
                   NULL);

  prop_subscribe(PROP_SUB_NO_INITIAL_UPDATE,
                 PROP_TAG_NAME("global", "runcontrol", "sleepTimer"),
		 PROP_TAG_CALLBACK_INT, update_sleeptimer, NULL,
		 NULL);
}
Esempio n. 18
0
static void
init_autostandby(void)
{
  setting_create(SETTING_INT, gconf.settings_general, SETTINGS_INITIAL_UPDATE,
                 SETTING_TITLE(_p("Automatic standby")),
                 SETTING_STORE("runcontrol", "autostandby"),
                 SETTING_WRITE_INT(&standby_delay),
                 SETTING_RANGE(0, 60),
                 SETTING_STEP(5),
                 SETTING_UNIT_CSTR("min"),
                 SETTING_ZERO_TEXT(_p("Off")),
                 NULL);

  last_activity = arch_get_ts();

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "playstatus"),
		 PROP_TAG_CALLBACK_STRING, current_media_playstatus, NULL,
		 NULL);

  callout_arm(&autostandby_timer, check_autostandby, NULL, 1);
}
Esempio n. 19
0
GtkWidget *
gu_playdeck_add(gu_window_t *gw, GtkWidget *parent)
{
  GtkToolItem *ti;
  GtkWidget *w;
  GtkWidget *l;
  GtkWidget *vbox;
  GtkWidget *playdeck;
  playdeck_t *pd = calloc(1, sizeof(playdeck_t));
  prop_courier_t *pc = gw->gw_gu->gu_pc;

  playdeck = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(parent), playdeck, FALSE, TRUE, 0);

  w = gtk_hseparator_new();
  gtk_widget_show(w);
  gtk_box_pack_start(GTK_BOX(playdeck), w, FALSE, TRUE, 0);
  

  pd->root = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(pd->root);
  gtk_box_pack_start(GTK_BOX(playdeck), pd->root, FALSE, TRUE, 0);

  /* Playdeck album art */
  w = gtk_image_new();
  gtk_widget_show(w);
  gtk_misc_set_alignment(GTK_MISC(w), 0, 1);
  gtk_box_pack_start(GTK_BOX(pd->root), w, FALSE, TRUE, 0);

  pd->sub_album_art = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "metadata", "album_art"),
		   PROP_TAG_CALLBACK_STRING, pd_set_albumart, w,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Middle vbox */
  vbox = gtk_vbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(pd->root), vbox, TRUE, TRUE, 0);

  
  /* Title of current track */
  l = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(l), 0, 0);
  gtk_box_pack_start(GTK_BOX(vbox), l, TRUE, TRUE, 0);
  g_object_set(G_OBJECT(l), 
	       "ellipsize", PANGO_ELLIPSIZE_END, NULL);

  pd->sub_title = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "metadata", "title"),
		   PROP_TAG_CALLBACK_STRING, set_current_title, l,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Title of current track */
  pd->trackextra = gtk_label_new("");
  g_object_set(G_OBJECT(pd->trackextra), 
	       "ellipsize", PANGO_ELLIPSIZE_END, NULL);
  gtk_misc_set_alignment(GTK_MISC(pd->trackextra), 0, 0);
  gtk_box_pack_start(GTK_BOX(vbox), pd->trackextra, TRUE, TRUE, 0);

  pd->sub_album = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "metadata", "album"),
		   PROP_TAG_CALLBACK_STRING, set_current_album, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);
  
  pd->sub_artist = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "metadata", "artist"),
		   PROP_TAG_CALLBACK_STRING, set_current_artist, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);



  /* The toolbar */
  pd->tbar = gtk_toolbar_new();
  gtk_toolbar_set_style(GTK_TOOLBAR(pd->tbar), GTK_TOOLBAR_ICONS);
  gtk_box_pack_start(GTK_BOX(vbox), pd->tbar, FALSE, TRUE, 0);

  /* Prev button */
  pd->prev = ti = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS);
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);
  g_signal_connect(G_OBJECT(ti), "clicked", G_CALLBACK(prev_clicked), pd);

  pd->sub_canSkipBackward =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "canSkipBackward"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   pd->prev,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Play / Pause */
  pd->playpause = ti = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);
  g_signal_connect(G_OBJECT(ti), "clicked", G_CALLBACK(playpause_clicked), pd);

  pd->sub_canPause =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "canPause"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   pd->playpause,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Next button */
  pd->next = ti = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_NEXT);
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);
  g_signal_connect(G_OBJECT(ti), "clicked", G_CALLBACK(next_clicked), pd);

  pd->sub_canSkipForward =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "canSkipForward"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   pd->next,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Separator */
  ti = gtk_separator_tool_item_new();
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);

  /* Subscribe to playstatus */
  pd->sub_playstatus =
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", "playstatus"),
		   PROP_TAG_CALLBACK, update_playstatus, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /**
   * Media position
   */
  pd->pos_adjust = gtk_adjustment_new(0, 0, 0, 0, 0, 0);

  pd->pos_slider = gtk_hscale_new(GTK_ADJUSTMENT(pd->pos_adjust));
  gtk_scale_set_value_pos (GTK_SCALE(pd->pos_slider), GTK_POS_LEFT);

  g_signal_connect(G_OBJECT(pd->pos_slider), "grab-focus", 
		   G_CALLBACK(slider_grabbed), pd);

  g_signal_connect(G_OBJECT(pd->pos_slider), "change-value", 
		   G_CALLBACK(slider_updated), pd);

  g_signal_connect(G_OBJECT(pd->pos_slider), "format-value", 
		   G_CALLBACK(slider_value_callback), pd);

  ti = gtk_tool_item_new();
  gtk_tool_item_set_expand(ti, TRUE);
  gtk_container_add(GTK_CONTAINER(ti), pd->pos_slider);
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);
  
  /* Subscribe to current track position */
  pd->sub_pos = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", "currenttime"),
		   PROP_TAG_CALLBACK_FLOAT, update_curtime, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);

  /* Subscribe to current track duration */
  pd->sub_duration = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "media", "current", 
				 "metadata", "duration"),
		   PROP_TAG_CALLBACK_FLOAT, update_duration, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);



  /* Separator */
  ti = gtk_separator_tool_item_new();
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);

  gtk_widget_show_all(vbox);

  /**
   * Volume control
   */
  ti = gtk_tool_item_new();
  pd->volume = gtk_volume_button_new();
  gtk_container_add(GTK_CONTAINER(ti), pd->volume);
  gtk_toolbar_insert(GTK_TOOLBAR(pd->tbar), ti, -1);

  g_signal_connect(G_OBJECT(pd->volume), "value-changed", 
		   G_CALLBACK(read_mastervol), pd);

  pd->sub_volume = 
    prop_subscribe(0,
		   PROP_TAG_NAME("global", "audio", "mastervolume"),
		   PROP_TAG_CALLBACK_FLOAT, update_mastervol, pd,
		   PROP_TAG_COURIER, pc,
		   NULL);
  gtk_widget_show_all(GTK_WIDGET(ti));

  g_signal_connect(playdeck, "destroy", G_CALLBACK(playdeck_dtor), pd);
  return playdeck;
}
Esempio n. 20
0
GtkWidget *
gu_toolbar_add(gu_tab_t *gt, GtkWidget *parent)
{
  toolbar_t *t = calloc(1, sizeof(toolbar_t));
  prop_courier_t *pc = gt->gt_gw->gw_gu->gu_pc;
  GtkWidget *toolbar;
  GtkWidget *w;

  t->gt = gt;

  /* Top Toolbar */
  toolbar = gtk_toolbar_new();
  gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
  gtk_box_pack_start(GTK_BOX(parent), toolbar, FALSE, TRUE, 0);

  /* Back button */
  t->back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), t->back, -1);
  g_signal_connect(G_OBJECT(t->back), "clicked", G_CALLBACK(back_clicked), gt);
  gtk_widget_show(GTK_WIDGET(t->back));

  /* Forward button */
  t->fwd = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), t->fwd, -1);
  g_signal_connect(G_OBJECT(t->fwd), "clicked", G_CALLBACK(fwd_clicked), gt);
  gtk_widget_show(GTK_WIDGET(t->fwd));
  
  /* Up button */
  t->up = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), t->up, -1);
  g_signal_connect(G_OBJECT(t->up), "clicked", G_CALLBACK(up_clicked), t);
  gtk_widget_show(GTK_WIDGET(t->up));

  /* Home button */
  t->home = gtk_tool_button_new_from_stock(GTK_STOCK_HOME);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), t->home, -1);
  g_signal_connect(G_OBJECT(t->home), "clicked", G_CALLBACK(home_clicked), gt);
  gtk_widget_show(GTK_WIDGET(t->home));


  /* URL entry */
  GtkToolItem *ti = gtk_tool_item_new();
  t->url = w = gtk_entry_new();

  g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(gu_nav_url_set), gt);

  gtk_container_add(GTK_CONTAINER(ti), w);
  gtk_tool_item_set_expand(ti, TRUE);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ti, -1);

  gtk_widget_show_all(GTK_WIDGET(ti));

  g_signal_connect(toolbar, "destroy", G_CALLBACK(toolbar_dtor), t);

  /* Opts button */
  t->opts = gtk_tool_button_new_from_stock(GTK_STOCK_EDIT);
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), t->opts, -1);
  g_signal_connect(G_OBJECT(t->opts), "clicked", G_CALLBACK(opts_clicked), gt);
  gtk_widget_show(GTK_WIDGET(t->opts));

  t->sub_canGoBack =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "canGoBack"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   t->back,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   NULL);

  t->sub_canGoFwd =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "canGoForward"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   t->fwd,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   NULL);

  t->sub_parent =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "currentpage", "parent"),
		   PROP_TAG_CALLBACK_STRING, set_go_up, t,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   NULL);

  t->sub_canGoHome =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "canGoHome"),
		   PROP_TAG_CALLBACK_INT, gu_subscription_set_sensitivity,
		   t->home,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   NULL);

  t->sub_url =
    prop_subscribe(0,
		   PROP_TAG_NAME("nav", "currentpage", "url"),
		   PROP_TAG_CALLBACK_STRING, gu_nav_url_updated, t,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gt->gt_nav, "nav",
		   NULL);

  gtk_widget_show_all(toolbar);

  return toolbar;
}
Esempio n. 21
0
void
upnp_avtransport_init(void)
{
  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "url"),
		 PROP_TAG_CALLBACK_STRING, set_current_str, &upnp_current_url,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "playstatus"),
		 PROP_TAG_CALLBACK_STRING, set_current_str, &upnp_current_playstatus,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "type"),
		 PROP_TAG_CALLBACK_STRING, set_current_str, &upnp_current_type,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", 
			       "metadata", "title"),
		 PROP_TAG_CALLBACK_STRING, set_current_str, &upnp_current_title,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", 
			       "metadata", "album"),
		 PROP_TAG_CALLBACK_STRING, set_current_str, &upnp_current_album,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", 
			       "metadata", "album_art"),
		 PROP_TAG_CALLBACK_STRING,
		 set_current_str, &upnp_current_album_art,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", 
			       "metadata", "artist"),
		 PROP_TAG_CALLBACK_STRING,
		 set_current_str, &upnp_current_artist,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", 
			       "metadata", "duration"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_track_duration,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "currentTrack"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_track,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "totalTracks"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_total_tracks,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "currenttime"),
		 PROP_TAG_CALLBACK_INT, set_current_int_passive, &upnp_current_track_time,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "shuffle"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_shuffle,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "repeat"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_repeat,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "canSkipBackward"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_canSkipBackward,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "canSkipForward"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_canSkipForward,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "canSeek"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_canSeek,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "canPause"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_canPause,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("global", "media", "current", "canStop"),
		 PROP_TAG_CALLBACK_INT, set_current_int, &upnp_current_canStop,
		 PROP_TAG_MUTEX, &upnp_lock,
		 NULL);

}
Esempio n. 22
0
void
background_init(prop_t *ui, prop_t *nav,
		void (*set_image)(rstr_t *url, const char **vpaths, 
				  void *opaque),
		void (*set_alpha)(float alpha, void *opaque),
		void *opaque)
{
  bg_helper_t *bgh = calloc(1, sizeof(bg_helper_t));
  bgh->pc = prop_courier_create_waitable();
  bgh->set_image = set_image;
  bgh->set_alpha = set_alpha;

  prop_subscribe(0,
		 PROP_TAG_NAME("ui","fullwindow"),
		 PROP_TAG_CALLBACK_INT, set_in_fullwindow, bgh,
		 PROP_TAG_ROOT, ui,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("ui","screensaverActive"),
		 PROP_TAG_CALLBACK_INT, set_in_screensaver, bgh,
		 PROP_TAG_ROOT, ui,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("ui","skin", "path"),
		 PROP_TAG_CALLBACK_RSTR, set_skin_path, bgh,
		 PROP_TAG_ROOT, ui,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("ui","background"),
		 PROP_TAG_CALLBACK_RSTR, set_bg2, bgh,
		 PROP_TAG_ROOT, ui,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("nav","currentpage","glw", "background"),
		 PROP_TAG_CALLBACK_RSTR, set_bg1, bgh,
		 PROP_TAG_ROOT, nav,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("nav","currentpage", "model", "metadata",
			       "background"),
		 PROP_TAG_CALLBACK_RSTR, set_bg0, bgh,
		 PROP_TAG_ROOT, nav,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("nav","currentpage","glw", "backgroundAlpha"),
		 PROP_TAG_CALLBACK_FLOAT, set_alpha1, bgh,
		 PROP_TAG_ROOT, nav,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  prop_subscribe(0,
		 PROP_TAG_NAME("nav","currentpage", "model", "metadata",
			       "backgroundAlpha"),
		 PROP_TAG_CALLBACK_FLOAT, set_alpha0, bgh,
		 PROP_TAG_ROOT, nav,
		 PROP_TAG_COURIER, bgh->pc,
		 NULL);

  hts_thread_create_detached("bgloader", bgloader_thread, bgh, 
			     THREAD_PRIO_UI_WORKER_LOW);
}
Esempio n. 23
0
File: glw.c Progetto: Allba/showtime
static void
glw_init_settings(glw_root_t *gr, const char *instance)
{
  prop_t *r = gr->gr_prop;

  if(gr->gr_base_size == 0)
    gr->gr_base_size = 20;

  gr->gr_settings_instance = strdup(instance);

  gr->gr_settings_store = htsmsg_store_load("displays/%s", instance);
  
  if(gr->gr_settings_store == NULL)
    gr->gr_settings_store = htsmsg_create_map();

  gr->gr_settings = settings_add_dir(NULL, 
				     _p("Display and user interface"),
				     "display", NULL, NULL, NULL);


  gr->gr_prop_size = prop_create(r, "size");
  gr->gr_prop_underscan_h = prop_create(r, "underscan_h");
  gr->gr_prop_underscan_v = prop_create(r, "underscan_v");


  gr->gr_setting_size =
    settings_create_int(gr->gr_settings, "size",
			_p("Userinterface size"), 0,
			gr->gr_settings_store, -10, 30, 1,
			glw_change_user_size, gr,
			SETTINGS_INITIAL_UPDATE, "px", gr->gr_courier,
			glw_settings_save, gr);

  gr->gr_setting_underscan_h =
    settings_create_int(gr->gr_settings, "underscan_h",
			_p("Horizontal underscan"), 0,
			gr->gr_settings_store, -100, +100, 1,
			glw_change_underscan_h, gr,
			SETTINGS_INITIAL_UPDATE, "px", gr->gr_courier,
			glw_settings_save, gr);

  gr->gr_setting_underscan_v =
    settings_create_int(gr->gr_settings, "underscan_v",
			_p("Vertical underscan"), 0,
			gr->gr_settings_store, -100, +100, 1,
			glw_change_underscan_v, gr,
			SETTINGS_INITIAL_UPDATE, "px", gr->gr_courier,
			glw_settings_save, gr);


  gr->gr_setting_screensaver =
    settings_create_int(gr->gr_settings, "screensaver",
			_p("Screensaver delay"),
			10, gr->gr_settings_store, 1, 60, 1,
			glw_set_screensaver_delay, gr,
			SETTINGS_INITIAL_UPDATE, " min", gr->gr_courier,
			glw_settings_save, gr);


  gr->gr_pointer_visible    = prop_create(r, "pointerVisible");
  gr->gr_is_fullscreen      = prop_create(r, "fullscreen");
  gr->gr_screensaver_active = prop_create(r, "screensaverActive");
  gr->gr_prop_width         = prop_create(r, "width");
  gr->gr_prop_height        = prop_create(r, "height");

  prop_set_int(gr->gr_screensaver_active, 0);

  gr->gr_evsub =
    prop_subscribe(0,
		   PROP_TAG_CALLBACK, glw_eventsink, gr,
		   PROP_TAG_NAME("ui", "eventSink"),
		   PROP_TAG_ROOT, r,
		   PROP_TAG_COURIER, gr->gr_courier,
		   NULL);
}
Esempio n. 24
0
static void
popup_create_auth(gtk_ui_t *gu, prop_t *p)
{
  GtkWidget *vbox, *hbox;
  GtkWidget *win;
  GtkWidget *l, *e, *w;
  prop_sub_t *s;

  popup_t *pop = calloc(1, sizeof(popup_t));

  pop->p = prop_ref_inc(p);
  LIST_INSERT_HEAD(&gu->popups, pop, link);

  /* The window */

  pop->win = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  
  gtk_window_set_title(GTK_WINDOW(win), "Authentication request");
  gtk_window_set_default_size(GTK_WINDOW(win), 400, 180);
  gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
  gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER_ON_PARENT);
  //  gtk_window_set_transient_for(GTK_WINDOW(win), GTK_WINDOW(gu->gu_window));


  /* Vbox */

  vbox = gtk_vbox_new(FALSE, 1);
  gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
  gtk_container_add(GTK_CONTAINER(win), vbox);

  /* ID label */
  l = gtk_label_new("");
  gtk_box_pack_start(GTK_BOX(vbox), l, FALSE, TRUE, 0);

  s = prop_subscribe(0,
		     PROP_TAG_NAME("self", "id"),
		     PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, l,
		     PROP_TAG_COURIER, glibcourier, 
		     PROP_TAG_NAMED_ROOT, p, "self",
		     NULL);
  gu_unsubscribe_on_destroy(GTK_OBJECT(l), s);

  /* Reason label */
  l = gtk_label_new("");
  gtk_box_pack_start(GTK_BOX(vbox), l, FALSE, TRUE, 0);

  s = prop_subscribe(0,
		     PROP_TAG_NAME("self", "reason"),
		     PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, l,
		     PROP_TAG_COURIER, glibcourier,
		     PROP_TAG_NAMED_ROOT, p, "self",
		     NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(l), s);

  /* Username */

  hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);

  l = gtk_label_new("Username:"******"activate", G_CALLBACK(auth_ok), pop);

  /* Password */

  hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);

  l = gtk_label_new("Password:"******"activate", G_CALLBACK(auth_ok), pop);


  /* Separator */

  w = gtk_hseparator_new();
  gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, TRUE, 0);

  /* Action buttons */

  hbox = gtk_hbutton_box_new();
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);

  w = gtk_button_new_from_stock(GTK_STOCK_OK);
  gtk_container_add(GTK_CONTAINER(hbox), w);
  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(auth_ok), pop);

  w = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
  gtk_container_add(GTK_CONTAINER(hbox), w);
  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(auth_cancel), pop);

  gtk_widget_show_all(win);
}
Esempio n. 25
0
static void
source_add(gtk_ui_t *gu, settinglist_t *sl,
	   prop_t *p, setting_t *s, setting_t *before,
	   int position)
{
  prop_sub_t *sub;
  GtkWidget *w, *vbox;
  prop_courier_t *pc = gu->gu_pc;

  s->s_settinglist = sl;
  s->s_hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(sl->sl_box), s->s_hbox, FALSE, TRUE, 5);
  gtk_box_reorder_child(GTK_BOX(sl->sl_box), s->s_hbox, position * 2);

  s->s_separator = gtk_hseparator_new();
  gtk_box_pack_start(GTK_BOX(sl->sl_box), s->s_separator, FALSE, TRUE, 0);
  gtk_box_reorder_child(GTK_BOX(sl->sl_box), s->s_separator, 
			position * 2 + 1);
  gtk_widget_show(s->s_separator);
  
  

  gtk_widget_set_size_request(s->s_hbox, -1, 64);

  /* Icon */
  w = gtk_image_new();
  gtk_box_pack_start(GTK_BOX(s->s_hbox), w, FALSE, TRUE, 5);

  sub = prop_subscribe(0,
		       PROP_TAG_NAME("self", "model", "metadata", "icon"),
		       PROP_TAG_CALLBACK_STRING, set_icon, w,
		       PROP_TAG_COURIER, pc, 
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);

  gtk_image_set_from_stock(GTK_IMAGE(w), GTK_STOCK_PROPERTIES,
			   GTK_ICON_SIZE_DIALOG);

  gtk_misc_set_alignment(GTK_MISC(w), 0.5, 0.5);
  gtk_misc_set_padding(GTK_MISC(w), 8, 0);

  /* vbox */
  vbox = gtk_vbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(s->s_hbox), vbox, TRUE, TRUE, 0);

  /* Title */
  w = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
  gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);
  gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, TRUE, 0);

  sub = 
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "model", "metadata", "title"),
		   PROP_TAG_CALLBACK_STRING, gu_subscription_set_label_xl, w,
		   PROP_TAG_COURIER, pc, 
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);


  /* Short description */
  w = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
  gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);
  gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, TRUE, 0);

  sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "model", "metadata", "shortdesc"),
		   PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, w,
		   PROP_TAG_COURIER, pc, 
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);


  /* Spacer */

  w = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), w, TRUE, FALSE, 0);

  /* Link */


#if 0
  hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0);

  w = gtk_button_new();
  gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);

  g_signal_connect(GTK_OBJECT(w),
		   "clicked", G_CALLBACK(source_clicked), s);

  g_object_set(G_OBJECT(w), "label", "Open", NULL);


  sub = prop_subscribe(0,
		       PROP_TAG_NAME("self", "url"),
		       PROP_TAG_CALLBACK_STRING, source_set_url, s,
		       PROP_TAG_COURIER, pc, 
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);
#endif

  /* Finalize */
  gtk_widget_show_all(s->s_hbox);
}
Esempio n. 26
0
static void
source_add(gtk_ui_t *gu, home_t *h, prop_t *p, source_t *s, source_t *before,
	   int position)
{
  prop_sub_t *sub;
  GtkWidget *w, *vbox, *hbox;

  s->s_home = h;
  s->s_hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(h->h_sourcebox), s->s_hbox, FALSE, TRUE, 5);
  gtk_box_reorder_child(GTK_BOX(h->h_sourcebox), s->s_hbox, position * 2);

  s->s_separator = gtk_hseparator_new();
  gtk_box_pack_start(GTK_BOX(h->h_sourcebox), s->s_separator, FALSE, TRUE, 0);
  gtk_box_reorder_child(GTK_BOX(h->h_sourcebox), s->s_separator, 
			position * 2 + 1);
  gtk_widget_show(s->s_separator);

  /* Icon */
  w = gtk_image_new();
  gtk_box_pack_start(GTK_BOX(s->s_hbox), w, FALSE, TRUE, 5);

  sub = prop_subscribe(0,
		       PROP_TAG_NAME("self", "icon"),
		       PROP_TAG_CALLBACK_STRING, home_set_icon, w,
		       PROP_TAG_COURIER, glibcourier,
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);

  gtk_image_set_from_stock(GTK_IMAGE(w), GTK_STOCK_DIRECTORY,
			   GTK_ICON_SIZE_DIALOG);

  gtk_misc_set_alignment(GTK_MISC(w), 0.5, 0.5);
  gtk_misc_set_padding(GTK_MISC(w), 12, 0);

  /* vbox */
  vbox = gtk_vbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(s->s_hbox), vbox, TRUE, TRUE, 0);

  /* Title */
  w = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
  gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);
  gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, TRUE, 0);

  sub = 
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "title"),
		   PROP_TAG_CALLBACK_STRING, gu_subscription_set_label_xl, w,
		   PROP_TAG_COURIER, glibcourier,
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);


  /* Status */
  w = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
  gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);
  gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, TRUE, 0);

  sub =
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "status"),
		   PROP_TAG_CALLBACK_STRING, gu_subscription_set_label, w,
		   PROP_TAG_COURIER, glibcourier,
		   PROP_TAG_NAMED_ROOT, p, "self",
		   NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);


  /* Spacer */

  w = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), w, TRUE, FALSE, 0);

  /* Link */



  hbox = gtk_hbox_new(FALSE, 1);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0);

  w = gtk_button_new();
  gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);

  g_signal_connect(GTK_OBJECT(w),
		   "clicked", G_CALLBACK(source_clicked), s);

  g_object_set(G_OBJECT(w), "label", "Open", NULL);


  sub = prop_subscribe(0,
		       PROP_TAG_NAME("self", "url"),
		       PROP_TAG_CALLBACK_STRING, source_set_url, s,
		       PROP_TAG_COURIER, glibcourier,
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

  gu_unsubscribe_on_destroy(GTK_OBJECT(w), sub);

  /* Finalize */
  gtk_widget_show_all(s->s_hbox);
}
Esempio n. 27
0
int
glw_init(glw_root_t *gr)
{
  char skinbuf[PATH_MAX];
  const char *skin = gconf.skin;

  if(gr->gr_prop_dispatcher == NULL)
    gr->gr_prop_dispatcher = &prop_courier_poll_timed;

  gr->gr_prop_maxtime = -1;

  assert(glw_settings.gs_settings != NULL);

  if(prop_set_parent(gr->gr_prop_ui, prop_get_global()))
    abort();

  if(prop_set_parent(gr->gr_prop_nav, prop_get_global()))
    abort();

  if(skin == NULL) {
    snprintf(skinbuf, sizeof(skinbuf),
	     "%s/glwskins/"SHOWTIME_GLW_DEFAULT_SKIN, showtime_dataroot());
    skin = skinbuf;
  }
  hts_mutex_init(&gr->gr_mutex);
  gr->gr_courier = prop_courier_create_passive();
  gr->gr_token_pool = pool_create("glwtokens", sizeof(token_t), POOL_ZERO_MEM);
  gr->gr_clone_pool = pool_create("glwclone", sizeof(glw_clone_t),
				  POOL_ZERO_MEM);

  gr->gr_skin = strdup(skin);

  gr->gr_vpaths[0] = "skin";
  gr->gr_vpaths[1] = gr->gr_skin;
  gr->gr_vpaths[2] = NULL;

  gr->gr_font_domain = freetype_get_context();

  glw_text_bitmap_init(gr);

  prop_setv(gr->gr_prop_ui, "skin", "path", NULL,
	    PROP_SET_STRING, gr->gr_skin);

  gr->gr_pointer_visible    = prop_create(gr->gr_prop_ui, "pointerVisible");
  gr->gr_is_fullscreen      = prop_create(gr->gr_prop_ui, "fullscreen");
  gr->gr_screensaver_active = prop_create(gr->gr_prop_ui, "screensaverActive");
  gr->gr_prop_width         = prop_create(gr->gr_prop_ui, "width");
  gr->gr_prop_height        = prop_create(gr->gr_prop_ui, "height");

  prop_set_int(gr->gr_screensaver_active, 0);

  gr->gr_evsub =
    prop_subscribe(0,
		   PROP_TAG_CALLBACK, glw_eventsink, gr,
		   PROP_TAG_NAME("ui", "eventSink"),
		   PROP_TAG_ROOT, gr->gr_prop_ui,
		   PROP_TAG_COURIER, gr->gr_courier,
		   NULL);

  TAILQ_INIT(&gr->gr_destroyer_queue);
  glw_tex_init(gr);

  gr->gr_framerate = 60;
  gr->gr_frameduration = 1000000 / gr->gr_framerate;
  gr->gr_ui_start = showtime_get_ts();

  gr->gr_open_osk = glw_osk_open;

  return 0;
}
Esempio n. 28
0
media_pipe_t *
mp_create(const char *name, int flags)
{
  media_pipe_t *mp;
  prop_t *p;

  mp = calloc(1, sizeof(media_pipe_t));
  mp->mp_cancellable = cancellable_create();

  mp->mp_vol_ui = 1.0f;

  mp->mp_satisfied = -1;
  mp->mp_epoch = 1;

  mp->mp_mb_pool = pool_create("packet headers",
			       sizeof(media_buf_t),
			       POOL_ZERO_MEM);

  mp->mp_flags = flags;

  hts_mutex_lock(&media_mutex);
  LIST_INSERT_HEAD(&media_pipelines, mp, mp_global_link);
  num_media_pipelines++;
  hts_mutex_unlock(&media_mutex);


  TAILQ_INIT(&mp->mp_eq);

  atomic_set(&mp->mp_refcount, 1);

  mp->mp_buffer_limit = 1 * 1024 * 1024;

  mp->mp_name = name;

  hts_mutex_init(&mp->mp_mutex);
  hts_mutex_init(&mp->mp_clock_mutex);

  hts_mutex_init(&mp->mp_overlay_mutex);
  TAILQ_INIT(&mp->mp_overlay_queue);
  TAILQ_INIT(&mp->mp_spu_queue);

  hts_cond_init(&mp->mp_backpressure, &mp->mp_mutex);

  mp->mp_prop_root = prop_create(media_prop_sources, NULL);
  mp->mp_prop_metadata    = prop_create(mp->mp_prop_root, "metadata");

  mp->mp_prop_primary = prop_create(mp->mp_prop_root, "primary");

  mp->mp_prop_io = prop_create(mp->mp_prop_root, "io");
  mp->mp_prop_notifications = prop_create(mp->mp_prop_root, "notifications");
  mp->mp_prop_url         = prop_create(mp->mp_prop_root, "url");


  mp->mp_setting_root = prop_create(mp->mp_prop_root, "settings");

  //--------------------------------------------------
  // Video

  mp->mp_prop_video = prop_create(mp->mp_prop_root, "video");
  mp->mp_setting_video_root = prop_create(mp->mp_prop_video, "settings");
  mq_init(&mp->mp_video, mp->mp_prop_video, &mp->mp_mutex, mp);

  //--------------------------------------------------
  // Audio

  mp->mp_prop_audio = prop_create(mp->mp_prop_root, "audio");
  mp->mp_setting_audio_root = prop_create(mp->mp_prop_audio, "settings");
  mq_init(&mp->mp_audio, mp->mp_prop_audio, &mp->mp_mutex, mp);
  mp->mp_prop_audio_track_current = prop_create(mp->mp_prop_audio, "current");
  mp->mp_prop_audio_track_current_manual =
    prop_create(mp->mp_prop_audio, "manual");
  mp->mp_prop_audio_tracks = prop_create(mp->mp_prop_metadata, "audiostreams");
  prop_linkselected_create(mp->mp_prop_audio_tracks,
                           mp->mp_prop_audio, "active", NULL);

  prop_set_string(mp->mp_prop_audio_track_current, "audio:off");


  mp_track_mgr_init(mp,
                    &mp->mp_audio_track_mgr,
                    mp->mp_prop_audio_tracks,
                    MEDIA_TRACK_MANAGER_AUDIO,
                    mp->mp_prop_audio_track_current,
                    prop_create(mp->mp_prop_audio, "sorted"));

  //--------------------------------------------------
  // Subtitles

  p = prop_create(mp->mp_prop_root, "subtitle");
  mp->mp_setting_subtitle_root = prop_create(p, "settings");
  mp->mp_prop_subtitle_track_current = prop_create(p, "current");
  mp->mp_prop_subtitle_track_current_manual = prop_create(p, "manual");
  mp->mp_prop_subtitle_tracks = prop_create(mp->mp_prop_metadata,
					    "subtitlestreams");
  prop_linkselected_create(mp->mp_prop_subtitle_tracks, p, "active", NULL);


  prop_set_string(mp->mp_prop_subtitle_track_current, "sub:off");
  mp_add_track_off(mp->mp_prop_subtitle_tracks, "sub:off");

  mp_track_mgr_init(mp,
                    &mp->mp_subtitle_track_mgr,
                    mp->mp_prop_subtitle_tracks,
                    MEDIA_TRACK_MANAGER_SUBTITLES,
                    mp->mp_prop_subtitle_track_current,
                    prop_create(p, "sorted"));

  //--------------------------------------------------
  // Buffer

  p = prop_create(mp->mp_prop_root, "buffer");
  mp->mp_prop_buffer_current = prop_create(p, "current");
  prop_set_int(mp->mp_prop_buffer_current, 0);

  mp->mp_prop_buffer_limit = prop_create(p, "limit");
  prop_set_int(mp->mp_prop_buffer_limit, mp->mp_buffer_limit);

  mp->mp_prop_buffer_delay = prop_create(p, "delay");



  //

  mp->mp_prop_playstatus  = prop_create(mp->mp_prop_root, "playstatus");
  mp->mp_prop_pausereason = prop_create(mp->mp_prop_root, "pausereason");
  mp->mp_prop_currenttime = prop_create(mp->mp_prop_root, "currenttime");
  mp->mp_prop_fps = prop_create(mp->mp_prop_root, "fps");

  prop_set_float_clipping_range(mp->mp_prop_currenttime, 0, 10e6);

  mp->mp_prop_avdelta     = prop_create(mp->mp_prop_root, "avdelta");
  prop_set_float(mp->mp_prop_avdelta, 0);

  mp->mp_prop_svdelta     = prop_create(mp->mp_prop_root, "svdelta");
  prop_set_float(mp->mp_prop_svdelta, 0);

  mp->mp_prop_shuffle     = prop_create(mp->mp_prop_root, "shuffle");
  prop_set_int(mp->mp_prop_shuffle, 0);
  mp->mp_prop_repeat      = prop_create(mp->mp_prop_root, "repeat");
  prop_set_int(mp->mp_prop_repeat, 0);

  mp->mp_prop_avdiff      = prop_create(mp->mp_prop_root, "avdiff");
  mp->mp_prop_avdiff_error= prop_create(mp->mp_prop_root, "avdiffError");

  mp->mp_prop_canSkipBackward =
    prop_create(mp->mp_prop_root, "canSkipBackward");

  mp->mp_prop_canSkipForward =
    prop_create(mp->mp_prop_root, "canSkipForward");

  mp->mp_prop_canSeek =
    prop_create(mp->mp_prop_root, "canSeek");

  mp->mp_prop_canPause =
    prop_create(mp->mp_prop_root, "canPause");

  mp->mp_prop_canEject =
    prop_create(mp->mp_prop_root, "canEject");

  mp->mp_prop_canShuffle =
    prop_create(mp->mp_prop_root, "canShuffle");

  mp->mp_prop_canRepeat =
    prop_create(mp->mp_prop_root, "canRepeat");

  prop_set_int(prop_create(mp->mp_prop_root, "canStop"), 1);

  mp->mp_prop_ctrl = prop_create(mp->mp_prop_root, "ctrl");

  mp->mp_prop_model = prop_create(mp->mp_prop_root, "model");

  mp->mp_sub_currenttime =
    prop_subscribe(PROP_SUB_NO_INITIAL_UPDATE,
		   PROP_TAG_CALLBACK, mp_seek_by_propchange, mp,
                   PROP_TAG_LOCKMGR, mp_lockmgr,
                   PROP_TAG_MUTEX, mp,
		   PROP_TAG_ROOT, mp->mp_prop_currenttime,
		   NULL);

  mp->mp_sub_eventsink =
    prop_subscribe(0,
		   PROP_TAG_NAME("media", "eventSink"),
                   PROP_TAG_CALLBACK_EVENT, media_eventsink, mp,
                   PROP_TAG_LOCKMGR, mp_lockmgr,
                   PROP_TAG_MUTEX, mp,
		   PROP_TAG_NAMED_ROOT, mp->mp_prop_root, "media",
		   NULL);


  if(media_pipe_init_extra != NULL)
    media_pipe_init_extra(mp);

  return mp;
}
Esempio n. 29
0
void
gu_video_create(gu_nav_page_t *gnp)
{
  prop_courier_t *pc = gnp->gnp_gt->gt_gw->gw_gu->gu_pc;
  struct video_output *vo;
  char errbuf[256];
  char buf[512];
  gu_video_t *gv;
  

  gnp->gnp_pageroot = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(gnp->gnp_pagebin), gnp->gnp_pageroot);
  gtk_widget_show_all(gnp->gnp_pageroot);

  vo = x11_vo_create(GDK_WINDOW_XDISPLAY(gnp->gnp_pageroot->window),
		     GDK_WINDOW_XID(gnp->gnp_pageroot->window),
		     pc, gnp->gnp_prop, errbuf, sizeof(errbuf));

  if(vo == NULL) {
    gtk_widget_destroy(gnp->gnp_pageroot);

    snprintf(buf, sizeof(buf), "Unable to start video: %s", errbuf);

    gnp->gnp_pageroot = gtk_label_new(buf);
    gtk_container_add(GTK_CONTAINER(gnp->gnp_pagebin), gnp->gnp_pageroot);
    gtk_widget_show_all(gnp->gnp_pageroot);
    return;
  }

  gv = calloc(1, sizeof(gu_video_t));

  gv->gv_closeprop = prop_ref_inc(prop_create(gnp->gnp_prop, "close"));

  gv->gv_status_sub = 
    prop_subscribe(0,
		   PROP_TAG_NAME("self", "media", "playstatus"),
		   PROP_TAG_CALLBACK_STRING, video_set_playstatus, gv,
		   PROP_TAG_COURIER, pc,
		   PROP_TAG_NAMED_ROOT, gnp->gnp_prop, "self",
		   NULL);

  g_signal_connect(GTK_OBJECT(gnp->gnp_pageroot), 
		   "destroy", G_CALLBACK(video_destroy), gv);

  g_signal_connect(G_OBJECT(gnp->gnp_pageroot), 
		   "expose_event",
                    G_CALLBACK(expose_event_callback), vo);

  g_signal_connect_after(G_OBJECT(gnp->gnp_pageroot), 
		   "configure_event",
                    G_CALLBACK(configure_event_callback), vo);

  g_signal_connect(GTK_OBJECT(gnp->gnp_pageroot), 
		   "unrealize", G_CALLBACK(video_unrealize), vo);

  g_signal_connect(G_OBJECT(gnp->gnp_pageroot), 
		   "button-press-event", 
		   G_CALLBACK(mouse_press), gnp);

  gtk_widget_add_events(gnp->gnp_pageroot, 
			GDK_BUTTON_PRESS_MASK |
			GDK_BUTTON_RELEASE_MASK);

  gu_page_set_fullwindow(gnp, 1);
}
static void
collection_albums(void *opaque, prop_event_t event, ...)
{
  albumbrowse_t *ab = opaque;
  prop_t *p;
  GtkWidget *w;
  GtkWidget *hbox;
  prop_sub_t *s;

  va_list ap;
  va_start(ap, event);

  switch(event) {
  case PROP_ADD_CHILD:
    p = va_arg(ap, prop_t *);
    
    /* Separator */

    if(ab->albums > 0) {
      w = gtk_hseparator_new();
      gtk_box_pack_start(GTK_BOX(ab->vbox), w, FALSE, FALSE, 5);
      gtk_widget_show(w);
    }

    ab->albums++;

    /* Album name */
    w = gtk_label_new("");
    gtk_misc_set_alignment(GTK_MISC(w), 0, 0);
    gtk_misc_set_padding(GTK_MISC(w), 5, 0);
    gtk_label_set_ellipsize(GTK_LABEL(w), PANGO_ELLIPSIZE_END);
    gtk_box_pack_start(GTK_BOX(ab->vbox), w, TRUE, TRUE, 0);
    gtk_widget_show(w);

    s = prop_subscribe(0,
		       PROP_TAG_NAME("self", "metadata", "album_name"),
		       PROP_TAG_CALLBACK_STRING, set_title, w,
		       PROP_TAG_COURIER, ab->gt->gt_gw->gw_gu->gu_pc, 
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

    gu_unsubscribe_on_destroy(GTK_OBJECT(w), s);


    /* hbox */

    hbox = gtk_hbox_new(FALSE, 1);
    gtk_box_pack_start(GTK_BOX(ab->vbox), hbox, TRUE, TRUE, 0);
    
    /* Album art */

    w = gtk_image_new();
    gtk_misc_set_alignment(GTK_MISC(w), 0.5, 0.0);
    gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, TRUE, 5);

    s = prop_subscribe(0,
		       PROP_TAG_NAME("self", "metadata", "album_art"),
		       PROP_TAG_CALLBACK_STRING, album_set_art, w,
		       PROP_TAG_COURIER, ab->gt->gt_gw->gw_gu->gu_pc, 
		       PROP_TAG_NAMED_ROOT, p, "self",
		       NULL);

    gu_unsubscribe_on_destroy(GTK_OBJECT(w), s);
    gtk_widget_show(w);

    /* Tracklist */
    w = gu_directory_list_create(ab->gt, p,
				 GU_DIR_COL_ARTIST |
				 GU_DIR_COL_DURATION |
				 GU_DIR_COL_TRACKINDEX);
    gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 0);
    gtk_widget_show_all(hbox);
    break;

  case PROP_SET_DIR:
  case PROP_SET_VOID:
    break;

  default:
    fprintf(stderr, 
	    "artist_albums(): Can not handle event %d, aborting()\n", event);
    abort();
  }
}