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); }
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; }
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); }
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; }
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); }
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); }
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); }
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); }
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_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; }
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); }
/** * 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(); }
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; }
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); }
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); }
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); }
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); }
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); }
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; }
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; }
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); }
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); }
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); }
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); }
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); }
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); }
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; }
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; }
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(); } }