From: Jaroslav Kysela Date: Fri, 15 Jan 2016 20:58:18 +0000 (+0100) Subject: wizard: implement tuner / network type dialog X-Git-Tag: v4.2.1~1158 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a0fe071ebcffd3ddd0fa3056da2d19c61f66cd60;p=thirdparty%2Ftvheadend.git wizard: implement tuner / network type dialog --- diff --git a/src/api/api_wizard.c b/src/api/api_wizard.c index 3d0aa6994..785fd3dae 100644 --- a/src/api/api_wizard.c +++ b/src/api/api_wizard.c @@ -24,14 +24,28 @@ #include "config.h" #include "wizard.h" +static int +wizard_page ( const char *page ) +{ + pthread_mutex_lock(&global_lock); + if (strcmp(page, config.wizard ?: "")) { + free(config.wizard); + config.wizard = page[0] ? strdup(page) : NULL; + config_save(); + } + pthread_mutex_unlock(&global_lock); + return 0; +} + static int wizard_idnode_load_simple ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { int r; wizard_build_fcn_t fcn = opaque; - wizard_page_t *page = fcn(); + wizard_page_t *page = fcn(perm->aa_lang_ui); r = api_idnode_load_simple(perm, &page->idnode, op, args, resp); + wizard_page(page->name); page->free(page); return r; } @@ -42,36 +56,24 @@ wizard_idnode_save_simple { int r; wizard_build_fcn_t fcn = opaque; - wizard_page_t *page = fcn(); + wizard_page_t *page = fcn(perm->aa_lang_ui); r = api_idnode_save_simple(perm, &page->idnode, op, args, resp); page->free(page); return r; } -static int -wizard_page - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp, const char *page ) -{ - pthread_mutex_lock(&global_lock); - free(config.wizard); - config.wizard = strdup(page); - config_save(); - pthread_mutex_unlock(&global_lock); - return 0; -} - static int wizard_cancel ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { - return wizard_page(perm, opaque, op, args, resp, ""); + return wizard_page(""); } static int wizard_start ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { - return wizard_page(perm, opaque, op, args, resp, "hello"); + return wizard_page("hello"); } void diff --git a/src/htsmsg.c b/src/htsmsg.c index 257cbfb16..14a69f3ea 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -935,7 +935,9 @@ htsmsg_copy_i(htsmsg_t *src, htsmsg_t *dst) htsmsg_t * htsmsg_copy(htsmsg_t *src) { - htsmsg_t *dst = src->hm_islist ? htsmsg_create_list() : htsmsg_create_map(); + htsmsg_t *dst; + if (src == NULL) return NULL; + dst = src->hm_islist ? htsmsg_create_list() : htsmsg_create_map(); htsmsg_copy_i(src, dst); return dst; } diff --git a/src/input.h b/src/input.h index 960360a16..0decc89cb 100644 --- a/src/input.h +++ b/src/input.h @@ -22,6 +22,8 @@ #include "idnode.h" #include "queue.h" +struct htsmsg; + /* * Type-defs */ @@ -87,6 +89,8 @@ struct tvh_input { void (*ti_get_streams) (tvh_input_t *, tvh_input_stream_list_t*); void (*ti_clear_stats) (tvh_input_t *); + struct htsmsg *(*ti_wizard_get) (tvh_input_t *, const char *); + void (*ti_wizard_set) (tvh_input_t *, struct htsmsg *); }; /* diff --git a/src/input/mpegts.h b/src/input/mpegts.h index e8e425e19..fbe1668e0 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -302,6 +302,8 @@ struct mpegts_network */ char *mn_network_name; char *mn_provider_network_name; + int mn_wizard; + uint8_t mn_wizard_free; /* * Inputs @@ -826,6 +828,7 @@ void mpegts_network_delete ( mpegts_network_t *mn, int delconf ); int mpegts_network_set_nid ( mpegts_network_t *mn, uint16_t nid ); int mpegts_network_set_network_name ( mpegts_network_t *mn, const char *name ); void mpegts_network_scan ( mpegts_network_t *mn ); +void mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen ); mpegts_mux_t *mpegts_mux_create0 ( mpegts_mux_t *mm, const idclass_t *class, const char *uuid, diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 91ff8edbc..35b8475b9 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -251,6 +251,13 @@ const idclass_t mpegts_network_class = .opts = PO_RDONLY | PO_NOSAVE, .get = mpegts_network_class_get_scanq_length, }, + { + .type = PT_BOOL, + .id = "wizard", + .name = N_("Wizard"), + .off = offsetof(mpegts_network_t, mn_wizard), + .opts = PO_NOUI + }, {} } }; @@ -449,6 +456,19 @@ mpegts_network_scan ( mpegts_network_t *mn ) mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); } +void +mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen ) +{ + const char *s = "IPTV"; +#if ENABLE_MPEGTS_DVB + dvb_fe_type_t ftype; + ftype = dvb_fe_type_by_network_class(mn->mn_id.in_class); + if (ftype != DVB_TYPE_NONE) + s = dvb_type2str(ftype); +#endif + snprintf(buf, buflen, "%s", s); +} + /****************************************************************************** * Network classes/creation *****************************************************************************/ diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index fa209f1dd..c1d1c6ab1 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -434,16 +434,7 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) if(m->mm_network->mn_network_name != NULL) si->si_network = strdup(m->mm_network->mn_network_name); -#if ENABLE_MPEGTS_DVB - dvb_fe_type_t ftype; - ftype = dvb_fe_type_by_network_class(m->mm_network->mn_id.in_class); - if (ftype == DVB_TYPE_NONE) - strcpy(buf, "IPTV"); - else - snprintf(buf, sizeof(buf), "%s", dvb_type2str(ftype)); -#else - strcpy(buf, "IPTV"); -#endif + mpegts_network_get_type_str(m->mm_network, buf, sizeof(buf)); si->si_network_type = strdup(buf); m->mm_display_name(m, buf, sizeof(buf)); diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 7b3d7e487..a725825d8 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -1752,8 +1752,69 @@ done: * Creation/Config * *************************************************************************/ +static int +satip_frontend_default_positions ( satip_frontend_t *lfe ) +{ + satip_device_t *sd = lfe->sf_device; + + if (!strcmp(sd->sd_info.modelname, "IPLNB")) + return 1; + return sd->sd_info.srcs; +} + +static htsmsg_t * +satip_frontend_wizard_get( tvh_input_t *ti, const char *lang ) +{ + satip_frontend_t *lfe = (satip_frontend_t*)ti; + htsmsg_t *m = htsmsg_create_map(), *l, *e; + satip_satconf_t *sfc; + const idclass_t *idc; + char ubuf[UUID_HEX_SIZE], buf[256]; + + sfc = TAILQ_FIRST(&lfe->sf_satconf); + if (sfc == NULL || (sfc && sfc->sfc_wizard)) { + lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); + htsmsg_add_str(m, "input_name", buf); + idc = dvb_network_class_by_fe_type(lfe->sf_type); + if (idc) { + l = htsmsg_create_list(); + e = htsmsg_create_map(); + htsmsg_add_str(e, "key", idc->ic_class); + htsmsg_add_str(e, "val", idclass_get_caption(idc, lang)); + htsmsg_add_msg(l, NULL, e); + htsmsg_add_msg(m, "mpegts_network_types", l); + } + if (sfc && sfc->sfc_wizard) { + lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); + htsmsg_add_str(m, "input_name", buf); + htsmsg_add_str(m, "mpegts_network", + idnode_uuid_as_str(sfc->sfc_networks->is_array[0], ubuf)); + } + } + return m; +} + +static void +satip_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf ) +{ + satip_frontend_t *lfe = (satip_frontend_t*)ti; + const char *uuid = htsmsg_get_str(conf, "mpegts_network_type"); + satip_satconf_t *sfc; + + sfc = TAILQ_FIRST(&lfe->sf_satconf); + if (uuid && (sfc == NULL || sfc->sfc_wizard)) { + htsmsg_t *conf = htsmsg_create_map(); + htsmsg_t *nlist = htsmsg_create_list(); + htsmsg_add_str(nlist, NULL, uuid); + htsmsg_add_msg(conf, "networks", nlist); + htsmsg_add_bool(conf, "wizard", 1); + satip_satconf_create(lfe, conf, satip_frontend_default_positions(lfe)); + htsmsg_destroy(conf); + } +} + static void -satip_frontend_hacks( satip_frontend_t *lfe, int *def_positions ) +satip_frontend_hacks( satip_frontend_t *lfe ) { satip_device_t *sd = lfe->sf_device; @@ -1764,8 +1825,6 @@ satip_frontend_hacks( satip_frontend_t *lfe, int *def_positions ) lfe->sf_play2 = 1; lfe->sf_tdelay = 250; lfe->sf_teardown_delay = 1; - } else if (!strcmp(sd->sd_info.modelname, "IPLNB")) { - *def_positions = 1; } else if (strstr(sd->sd_info.manufacturer, "AVM Berlin") && strstr(sd->sd_info.modelname, "FRITZ!")) { lfe->sf_play2 = 1; @@ -1781,7 +1840,7 @@ satip_frontend_create char id[16], lname[256], nname[60]; satip_frontend_t *lfe; uint32_t master = 0; - int i, def_positions = sd->sd_info.srcs; + int i; /* Override type */ snprintf(id, sizeof(id), "override #%d", num); @@ -1838,7 +1897,7 @@ satip_frontend_create lfe->sf_master = master; lfe->sf_type_override = override ? strdup(override) : NULL; lfe->sf_pass_weight = 1; - satip_frontend_hacks(lfe, &def_positions); + satip_frontend_hacks(lfe); TAILQ_INIT(&lfe->sf_satconf); pthread_mutex_init(&lfe->sf_dvr_lock, NULL); lfe = (satip_frontend_t*)mpegts_input_create0((mpegts_input_t*)lfe, idc, uuid, conf); @@ -1865,6 +1924,8 @@ satip_frontend_create } /* Input callbacks */ + lfe->ti_wizard_get = satip_frontend_wizard_get; + lfe->ti_wizard_set = satip_frontend_wizard_set; lfe->mi_is_enabled = satip_frontend_is_enabled; lfe->mi_start_mux = satip_frontend_start_mux; lfe->mi_stop_mux = satip_frontend_stop_mux; @@ -1879,7 +1940,7 @@ satip_frontend_create /* Create satconf */ if (lfe->sf_type == DVB_TYPE_S && master == 0) - satip_satconf_create(lfe, conf, def_positions); + satip_satconf_create(lfe, conf, satip_frontend_default_positions(lfe)); /* Slave networks update */ if (master) { diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 21fd4a440..e0a349479 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -177,6 +177,7 @@ struct satip_satconf /* * Config */ + int sfc_wizard; int sfc_enabled; int sfc_position; int sfc_priority; diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 35254c09e..e60f7e102 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -183,6 +183,13 @@ const idclass_t satip_satconf_class = .ic_get_title = satip_satconf_class_get_title, .ic_save = satip_satconf_class_save, .ic_properties = (const property_t[]) { + { + .type = PT_BOOL, + .id = "wizard", + .name = N_("Wizard"), + .off = offsetof(satip_satconf_t, sfc_wizard), + .opts = PO_NOUI, + }, { .type = PT_BOOL, .id = "enabled", diff --git a/src/queue.h b/src/queue.h index 6bc9af8e8..1551ea3ef 100644 --- a/src/queue.h +++ b/src/queue.h @@ -11,6 +11,22 @@ * Extra LIST-ops */ +#define LIST_LAST(headname, head, field) ({ \ + headname *r; \ + for (r = LIST_FIRST(head); \ + LIST_NEXT(r, field); \ + r = LIST_NEXT(r, field)); \ + r; \ +}) + +#define LIST_PREV(elm, headname, head, field) ({ \ + headname *r; \ + for (r = LIST_FIRST(head); \ + r && LIST_NEXT(r, field) != (elm); \ + r = LIST_NEXT(r, field)); \ + r; \ +}) + #define LIST_ENTRY_INIT(elm, field) \ (elm)->field.le_next = NULL, (elm)->field.le_prev = NULL diff --git a/src/wizard.c b/src/wizard.c index f49a6aded..1dce07402 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -87,10 +87,12 @@ static void page_free(wizard_page_t *page) free(page); } -static wizard_page_t *page_init(const char *class_name, const char *caption) +static wizard_page_t *page_init + (const char *name, const char *class_name, const char *caption) { wizard_page_t *page = calloc(1, sizeof(*page)); idclass_t *ic = calloc(1, sizeof(*ic)); + page->name = name; page->idnode.in_class = ic; ic->ic_caption = caption; ic->ic_class = ic->ic_event = class_name; @@ -165,7 +167,7 @@ Enter the languages for the web user interface and \ for EPG texts.\ ")) -wizard_page_t *wizard_hello(void) +wizard_page_t *wizard_hello(const char *lang) { static const property_group_t groups[] = { { @@ -221,7 +223,7 @@ wizard_page_t *wizard_hello(void) {} }; wizard_page_t *page = - page_init("wizard_hello", + page_init("hello", "wizard_hello", N_("Welcome - Tvheadend - your TV streaming server and video recorder")); idclass_t *ic = (idclass_t *)page->idnode.in_class; wizard_hello_t *w; @@ -369,7 +371,7 @@ This wizard should be run only on the initial setup. Please, cancel \ it, if you are not willing to touch the current configuration.\ ")) -wizard_page_t *wizard_login(void) +wizard_page_t *wizard_login(const char *lang) { static const property_group_t groups[] = { { @@ -434,7 +436,7 @@ wizard_page_t *wizard_login(void) {} }; wizard_page_t *page = - page_init("wizard_login", + page_init("login", "wizard_login", N_("Welcome - Tvheadend - your TV streaming server and video recorder")); idclass_t *ic = (idclass_t *)page->idnode.in_class; wizard_login_t *w; @@ -477,78 +479,206 @@ wizard_page_t *wizard_login(void) /* * Network settings */ +#define WIZARD_NETWORKS 6 typedef struct wizard_network { - char network_type1[32]; - char network_type2[32]; - char network_type3[32]; - char network_type4[32]; + property_t props [WIZARD_NETWORKS * 3 + 10]; + char tuner [WIZARD_NETWORKS][64]; + char tunerid [WIZARD_NETWORKS][UUID_HEX_SIZE]; + char network_type[WIZARD_NETWORKS][64]; + htsmsg_t *network_types[WIZARD_NETWORKS]; } wizard_network_t; -#define NETWORK(num, nameval) { \ +static void network_free(wizard_page_t *page) +{ + wizard_network_t *w = page->aux; + int idx; + + for (idx = 0; idx < WIZARD_NETWORKS; idx++) + htsmsg_destroy(w->network_types[idx]); + page_free(page); +} + +static void network_save(idnode_t *in) +{ + wizard_page_t *p = (wizard_page_t *)in; + wizard_network_t *w = p->aux; + mpegts_network_t *mn, *mn_next; + tvh_input_t *ti; + htsmsg_t *m; + int idx; + + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) + if (mn->mn_wizard) + mn->mn_wizard_free = 1; + for (idx = 0; idx < WIZARD_NETWORKS; idx++) { + if (w->network_type[idx][0] == '\0') + continue; + ti = tvh_input_find_by_uuid(w->tunerid[idx]); + if (ti == NULL || ti->ti_wizard_set == NULL) + continue; + m = htsmsg_create_map(); + htsmsg_add_str(m, "mpegts_network_type", w->network_type[idx]); + ti->ti_wizard_set(ti, m); + htsmsg_destroy(m); + } + for (mn = LIST_FIRST(&mpegts_network_all); mn != NULL; mn = mn_next) { + mn_next = LIST_NEXT(mn, mn_global_link); + if (mn->mn_wizard_free) + mn->mn_delete(mn, 1); + } +} + +#define NETWORK_GROUP(num) { \ + .name = N_("Network " STRINGIFY(num)), \ + .number = num, \ +} + +#define NETWORK(num) { \ + .type = PT_STR, \ + .id = "tuner" STRINGIFY(num), \ + .name = N_("Tuner"), \ + .get = network_get_tvalue##num, \ + .opts = PO_RDONLY, \ + .group = num, \ +}, { \ + .type = PT_STR, \ + .id = "hidden_tunerid" STRINGIFY(num), \ + .name = "Tuner", \ + .get = network_get_tidvalue##num, \ + .opts = PO_RDONLY | PO_NOUI, \ +}, { \ .type = PT_STR, \ .id = "network" STRINGIFY(num), \ - .name = nameval, \ + .name = N_("Network type"), \ .get = network_get_value##num, \ .set = network_set_value##num, \ - .list = network_get_list, \ + .list = network_get_list##num, \ + .group = num, \ } #define NETWORK_FCN(num) \ +static const void *network_get_tvalue##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_network_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->tuner[num-1]); \ + return &prop_sbuf_ptr; \ +} \ +static const void *network_get_tidvalue##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_network_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->tunerid[num-1]); \ + return &prop_sbuf_ptr; \ +} \ static const void *network_get_value##num(void *o) \ { \ wizard_page_t *p = o; \ wizard_network_t *w = p->aux; \ - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->network_type##num); \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->network_type[num-1]); \ return &prop_sbuf_ptr; \ } \ static int network_set_value##num(void *o, const void *v) \ { \ wizard_page_t *p = o; \ wizard_network_t *w = p->aux; \ - snprintf(w->network_type##num, sizeof(w->network_type##num), "%s", (const char *)v); \ + snprintf(w->network_type[num-1], sizeof(w->network_type[num-1]), "%s", (const char *)v); \ return 1; \ +} \ +static htsmsg_t *network_get_list##num(void *o, const char *lang) \ +{ \ + if (o == NULL) return NULL; \ + wizard_page_t *p = o; \ + wizard_network_t *w = p->aux; \ + return htsmsg_copy(w->network_types[num-1]); \ } NETWORK_FCN(1) NETWORK_FCN(2) NETWORK_FCN(3) NETWORK_FCN(4) +NETWORK_FCN(5) +NETWORK_FCN(6) DESCRIPTION_FCN(network, N_("\ -Create networks. The T means terresterial, C is cable and S is satellite.\ +Select network type for detected tuners.\n\ +The T means terresterial, C is cable and S is satellite.\ ")) -static htsmsg_t *network_get_list(void *o, const char *lang) -{ - mpegts_network_builder_t *mnb; - htsmsg_t *e, *l = htsmsg_create_list(); - LIST_FOREACH(mnb, &mpegts_network_builders, link) { - e = htsmsg_create_map(); - htsmsg_add_str(e, "key", mnb->idc->ic_class); - htsmsg_add_str(e, "val", idclass_get_caption(mnb->idc, lang)); - htsmsg_add_msg(l, NULL, e); - } - return l; -} -wizard_page_t *wizard_network(void) +wizard_page_t *wizard_network(const char *lang) { + static const property_group_t groups[] = { + NETWORK_GROUP(1), + NETWORK_GROUP(2), + NETWORK_GROUP(3), + NETWORK_GROUP(4), + NETWORK_GROUP(5), + NETWORK_GROUP(6), + {} + }; + static const property_t nprops[] = { + NETWORK(1), + NETWORK(2), + NETWORK(3), + NETWORK(4), + NETWORK(5), + NETWORK(6), + }; static const property_t props[] = { - NETWORK(1, N_("Network 1")), - NETWORK(2, N_("Network 2")), - NETWORK(3, N_("Network 3")), - NETWORK(4, N_("Network 4")), ICON(), DESCRIPTION(network), PREV_BUTTON(login), NEXT_BUTTON(input), - {} }; - wizard_page_t *page = page_init("wizard_network", N_("Network settings")); + wizard_page_t *page = page_init("network", "wizard_network", N_("Network settings")); idclass_t *ic = (idclass_t *)page->idnode.in_class; - ic->ic_properties = props; - page->aux = calloc(1, sizeof(wizard_network_t)); + wizard_network_t *w; + mpegts_network_t *mn; + tvh_input_t *ti; + const char *name; + htsmsg_t *m; + int idx, nidx = 0; + + page->aux = w = calloc(1, sizeof(wizard_network_t)); + ic->ic_groups = groups; + ic->ic_properties = w->props; + ic->ic_save = network_save; + page->free = network_free; + + for (idx = 0; idx < ARRAY_SIZE(props); idx++) + w->props[idx] = props[idx]; + + for (ti = LIST_LAST(tvh_input_t, &tvh_inputs, ti_link); ti; + ti = LIST_PREV(ti, tvh_input_t, &tvh_inputs, ti_link)) { + if (ti->ti_wizard_get == NULL) + continue; + m = ti->ti_wizard_get(ti, lang); + if (m == NULL) + continue; + name = htsmsg_get_str(m, "input_name"); + if (name) { + snprintf(w->tuner[nidx], sizeof(w->tuner[nidx]), "%s", name); + idnode_uuid_as_str(&ti->ti_id, w->tunerid[nidx]); + mn = mpegts_network_find(htsmsg_get_str(m, "mpegts_network")); + if (mn) { + snprintf(w->network_type[nidx], sizeof(w->network_type[nidx]), "%s", + mn->mn_id.in_class->ic_class); + } + w->network_types[nidx] = htsmsg_copy(htsmsg_get_list(m, "mpegts_network_types")); + w->props[idx++] = nprops[nidx * 3 + 0]; + w->props[idx++] = nprops[nidx * 3 + 1]; + w->props[idx++] = nprops[nidx * 3 + 2]; + nidx++; + } + htsmsg_destroy(m); + if (nidx >= WIZARD_NETWORKS) + break; + } + + assert(idx < ARRAY_SIZE(w->props)); + return page; } @@ -561,7 +691,7 @@ Assign inputs to networks.\ ")) -wizard_page_t *wizard_input(void) +wizard_page_t *wizard_input(const char *lang) { static const property_t props[] = { { @@ -591,7 +721,7 @@ wizard_page_t *wizard_input(void) NEXT_BUTTON(status), {} }; - wizard_page_t *page = page_init("wizard_input", N_("Input / tuner settings")); + wizard_page_t *page = page_init("input", "wizard_input", N_("Input / tuner settings")); idclass_t *ic = (idclass_t *)page->idnode.in_class; ic->ic_properties = props; return page; @@ -606,7 +736,7 @@ Show the scan status.\ ")) -wizard_page_t *wizard_status(void) +wizard_page_t *wizard_status(const char *lang) { static const property_t props[] = { { @@ -631,7 +761,7 @@ wizard_page_t *wizard_status(void) NEXT_BUTTON(mapping), {} }; - wizard_page_t *page = page_init("wizard_status", N_("Scan status")); + wizard_page_t *page = page_init("status", "wizard_status", N_("Scan status")); idclass_t *ic = (idclass_t *)page->idnode.in_class; ic->ic_properties = props; return page; @@ -646,7 +776,7 @@ Do the service mapping to channels.\ ")) -wizard_page_t *wizard_mapping(void) +wizard_page_t *wizard_mapping(const char *lang) { static const property_t props[] = { { @@ -663,7 +793,7 @@ wizard_page_t *wizard_mapping(void) LAST_BUTTON(), {} }; - wizard_page_t *page = page_init("wizard_service_map", N_("Service mapping")); + wizard_page_t *page = page_init("mapping", "wizard_service_map", N_("Service mapping")); idclass_t *ic = (idclass_t *)page->idnode.in_class; ic->ic_properties = props; return page; diff --git a/src/wizard.h b/src/wizard.h index b0bef71f0..71768b9eb 100644 --- a/src/wizard.h +++ b/src/wizard.h @@ -24,17 +24,18 @@ typedef struct wizard_page { idnode_t idnode; + const char *name; void (*free)(struct wizard_page *); void *aux; } wizard_page_t; -typedef wizard_page_t *(*wizard_build_fcn_t)(void); +typedef wizard_page_t *(*wizard_build_fcn_t)(const char *lang); -wizard_page_t *wizard_hello(void); -wizard_page_t *wizard_login(void); -wizard_page_t *wizard_network(void); -wizard_page_t *wizard_input(void); -wizard_page_t *wizard_status(void); -wizard_page_t *wizard_mapping(void); +wizard_page_t *wizard_hello(const char *lang); +wizard_page_t *wizard_login(const char *lang); +wizard_page_t *wizard_network(const char *lang); +wizard_page_t *wizard_input(const char *lang); +wizard_page_t *wizard_status(const char *lang); +wizard_page_t *wizard_mapping(const char *lang); #endif /* __TVH_WIZARD_H__ */