event_t * popup_display(prop_t *p) { prop_courier_t *pc = prop_courier_create_waitable(); event_t *e = NULL; prop_t *r = prop_create(p, "eventSink"); prop_sub_t *s = prop_subscribe(0, PROP_TAG_CALLBACK, eventsink, &e, PROP_TAG_ROOT, r, PROP_TAG_COURIER, pc, NULL); /* Will show the popup */ if(prop_set_parent(p, prop_create(prop_get_global(), "popups"))) { /* popuproot is a zombie, this is an error */ abort(); } while(e == NULL) prop_courier_wait_and_dispatch(pc); prop_unsubscribe(s); return e; }
static void trace_prop(int l, const char *pfx, const char *msg, const char *sev) { trace_entry_t *te = malloc(sizeof(trace_entry_t)); te->p = prop_create_root(NULL); prop_set_string(prop_create(te->p, "prefix"), pfx); prop_set_string(prop_create(te->p, "message"), msg); prop_set_string(prop_create(te->p, "severity"), sev); TAILQ_INSERT_TAIL(&traces, te, link); if(prop_set_parent(te->p, log_root)) abort(); entries++; if(entries > 50) { te = TAILQ_FIRST(&traces); TAILQ_REMOVE(&traces, te, link); prop_destroy(te->p); free(te); entries--; } }
int search_class_create(prop_t *parent, prop_t **nodesp, prop_t **entriesp, const char *title, const char *icon) { prop_t *p = prop_create_root(NULL); prop_t *m = prop_create(p, "metadata"); prop_t *n, *e; char url[URL_MAX]; backend_prop_make(p, url, sizeof(url)); prop_set_string(prop_create(p, "url"), url); prop_set_string(prop_create(m, "title"), title); if(icon != NULL) prop_set_string(prop_create(m, "icon"), icon); prop_set_string(prop_create(p, "type"), "directory"); n = prop_create(p, "nodes"); e = prop_create(p, "entries"); prop_set_int(e, 0); *nodesp = prop_ref_inc(n); *entriesp = prop_ref_inc(e); if(prop_set_parent(p, parent)) { prop_destroy(p); return 1; } return 0; }
static void nav_reload_current(navigator_t *nav) { nav_page_t *np; if((np = nav->nav_page_current) == NULL) return; plugins_reload_dev_plugin(); TRACE(TRACE_INFO, "navigator", "Reloading %s", np->np_url); prop_unsubscribe(np->np_close_sub); prop_unsubscribe(np->np_direct_close_sub); prop_destroy(np->np_prop_root); nav_page_setup_prop(nav, np, NULL); if(prop_set_parent(np->np_prop_root, nav->nav_prop_pages)) { /* nav->nav_prop_pages is a zombie, this is an error */ abort(); } nav_select(nav, np, NULL); if(backend_open(np->np_prop_root, np->np_url)) nav_open_errorf(np->np_prop_root, _("No handler for URL")); }
prop_t * add_news(const char *message, const char *location, const char *caption) { prop_t *p, *ret = NULL; prop_t *root = prop_create(prop_get_global(), "news"); hts_mutex_lock(&news_mutex); if(dismissed_news_out != NULL) { if(htsmsg_get_u32_or_default(dismissed_news_in, message, 0)) { dismis_news(message); } else { p = prop_create_root(NULL); prop_set_string(prop_create(p, "message"), message); prop_set_string(prop_create(p, "location"), location); prop_set_string(prop_create(p, "caption"), caption); prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, news_sink, prop_ref_inc(p), PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); ret = prop_ref_inc(p); if(prop_set_parent(p, root)) prop_destroy(p); } } hts_mutex_unlock(&news_mutex); return ret; }
static prop_t * add_news_locked(const char *id, const char *message, const char *location, const char *caption, const char *action) { prop_t *p, *ret = NULL; prop_t *root = prop_create(prop_get_global(), "news"); if(dismissed_news_out != NULL) { if(htsmsg_get_u32_or_default(dismissed_news_in, id, 0)) { dismis_news(id); } else { p = prop_create_root(id); prop_set(p, "message", PROP_SET_STRING, message); prop_set(p, "id", PROP_SET_STRING, id); prop_set(p, "location", PROP_SET_STRING, location); prop_set(p, "caption", PROP_SET_STRING, caption); prop_set(p, "action", PROP_SET_STRING, action); prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, news_sink, prop_ref_inc(p), PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); ret = prop_ref_inc(p); if(prop_set_parent(p, root)) prop_destroy(p); } } return ret; }
static void nav_insert_page(navigator_t *nav, nav_page_t *np, prop_t *origin) { nav_page_t *np2; if(prop_set_parent(np->np_prop_root, nav->nav_prop_pages)) { /* nav->nav_prop_pages is a zombie, this is an error */ abort(); } if(np->np_inhistory == 0) { if(nav->nav_page_current != NULL) { /* Destroy any previous "future" histories, * this happens if we back a few times and then jumps away * in another "direction" */ while((np2 = TAILQ_NEXT(nav->nav_page_current, np_history_link)) != NULL) nav_close(np2, 1); } TAILQ_INSERT_TAIL(&nav->nav_history, np, np_history_link); np->np_inhistory = 1; } nav_select(nav, np, origin); }
static void bookmark_add(const char *title, const char *url, const char *type) { bookmark_t *bm = calloc(1, sizeof(bookmark_t)); prop_t *p = prop_create_root(NULL); prop_t *src = prop_create(p, "model"); prop_set_string(prop_create(src, "type"), "bookmark"); bm->bm_title_sub = bookmark_add_prop(src, "title", title, bm, set_title); bm->bm_url_sub = bookmark_add_prop(src, "url", url, bm, set_url); bm->bm_type_sub = bookmark_add_prop(src, "svctype", type, bm, set_type); bm->bm_service = service_create(title, url, type, NULL, 1, 1); prop_link(service_get_status_prop(bm->bm_service), prop_create(src, "status")); prop_link(service_get_statustxt_prop(bm->bm_service), prop_create(src, "statustxt")); prop_subscribe(PROP_SUB_TRACK_DESTROY | PROP_SUB_NO_INITIAL_UPDATE, PROP_TAG_CALLBACK, bookmark_destroyed, bm, PROP_TAG_ROOT, p, PROP_TAG_MUTEX, &bookmark_mutex, NULL); if(prop_set_parent(p, prop_create(bookmarks, "nodes"))) abort(); }
static JSBool js_item_addOptAction(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { js_item_t *ji = JS_GetPrivate(cx, obj); const char *title; const char *action; if (!JS_ConvertArguments(cx, argc, argv, "ss", &title, &action)) return JS_FALSE; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "action"); prop_set_string(prop_create(prop_create(p, "metadata"), "title"), title); prop_set_int(prop_create(p, "enabled"), 1); prop_set_string(prop_create(p, "action"), action); prop_t *opts = prop_create_r(ji->ji_root, "options"); if(prop_set_parent(p, opts)) prop_destroy(p); prop_ref_dec(opts); *rval = JSVAL_VOID; return JS_TRUE; }
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; }
int message_popup(const char *message, int flags, const char **extra) { prop_t *p; int rval; p = prop_ref_inc(prop_create_root(NULL)); TRACE(TRACE_DEBUG, "Notification", "%s", message); prop_set_string(prop_create(p, "type"), "message"); prop_set_string_ex(prop_create(p, "message"), NULL, message, flags & MESSAGE_POPUP_RICH_TEXT ? PROP_STR_RICH : PROP_STR_UTF8); if(extra) { int cnt = 1; prop_t *btns = prop_create(p, "buttons"); while(*extra) { prop_t *b = prop_create_root(NULL); prop_set_string(prop_create(b, "title"), *extra); char action[10]; snprintf(action, sizeof(action), "btn%d", cnt); prop_set_string(prop_create(b, "action"), action); if(prop_set_parent(b, btns)) abort(); cnt++; extra++; } } if(flags & MESSAGE_POPUP_CANCEL) prop_set_int(prop_create(p, "cancel"), 1); if(flags & MESSAGE_POPUP_OK) prop_set_int(prop_create(p, "ok"), 1); event_t *e = popup_display(p); prop_destroy(p); prop_ref_dec(p); const event_payload_t *ep = (const event_payload_t *)e; if(event_is_action(e, ACTION_OK)) rval = MESSAGE_POPUP_OK; else if(event_is_action(e, ACTION_CANCEL)) rval = MESSAGE_POPUP_CANCEL; else if(event_is_type(e, EVENT_DYNAMIC_ACTION) && !strncmp(ep->payload, "btn", 3)) rval = atoi(ep->payload + 3); else rval = 0; event_release(e); return rval; }
static JSBool js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent, const char *url, const char *type, JSObject *metaobj, jsval *data, jsval *rval, int enabled, const char *metabind) { prop_t *item = prop_create_root(NULL); if(url != NULL) prop_set_string(prop_create(item, "url"), url); if(data != NULL) js_prop_set_from_jsval(cx, prop_create(item, "data"), *data); *rval = JSVAL_VOID; if(metabind != NULL) metadb_bind_url_to_prop(NULL, metabind, item); if(type != NULL) { prop_set_string(prop_create(item, "type"), type); if(metaobj) js_prop_from_object(cx, metaobj, prop_create(item, "metadata")); } else if(url != NULL) { if(backend_resolve_item(url, item)) { prop_destroy(item); return JS_TRUE; } } prop_set_int(prop_create(item, "enabled"), enabled); prop_t *p = prop_ref_inc(item); if(prop_set_parent(item, parent)) { prop_destroy(item); prop_ref_dec(p); } else { JSObject *robj = JS_NewObjectWithGivenProto(cx, &item_class, JSVAL_TO_OBJECT(model->jm_item_proto), NULL); *rval = OBJECT_TO_JSVAL(robj); js_item_t *ji = calloc(1, sizeof(js_item_t)); ji->ji_model = model; ji->ji_root = p; LIST_INSERT_HEAD(&model->jm_items, ji, ji_link); JS_SetPrivate(cx, robj, ji); ji->ji_enable_set_property = 1; } return JS_TRUE; }
static int file_open_image(prop_t *page, prop_t *meta) { prop_t *model = prop_create(page, "model"); prop_set_string(prop_create(model, "type"), "image"); if(prop_set_parent(meta, model)) abort(); return 0; }
/** * Popup an request to the user on behalf of connman */ static GVariant * agent_request_input(connman_service_t *cs, GVariant *req, GDBusMethodInvocation *inv) { TRACE(TRACE_INFO, "CONNMAN", "Requesting credentials for %s", cs->cs_path); TRACE(TRACE_DEBUG, "CONNMAN", "RequestInput: %s", g_variant_print(req, TRUE)); prop_t *p = prop_create_root(NULL); prop_set(p, "type", PROP_SET_STRING, "auth"); prop_set(p, "id", PROP_SET_STRING, cs->cs_path); prop_set(p, "source", PROP_SET_STRING, "Network"); GVariant *prev = g_variant_lookup_value(req, "PreviousPassphrase", NULL); if(prev) { prop_set(p, "reason", PROP_SET_STRING, "Password incorrect"); } else { prop_set(p, "reason", PROP_SET_STRING, "Password needed"); } GVariant *identity = g_variant_lookup_value(req, "Identity", NULL); cs->cs_input_req_want_identity = identity != NULL; prop_set(p, "disableUsername", PROP_SET_INT, !cs->cs_input_req_want_identity); prop_set(p, "disableDomain", PROP_SET_INT, 1); prop_t *r = prop_create(p, "eventSink"); cs->cs_input_req_sub = prop_subscribe(0, PROP_TAG_CALLBACK_EVENT, input_req_event, cs, PROP_TAG_NAMED_ROOT, r, "popup", PROP_TAG_COURIER, connman_courier, NULL); cs->cs_input_req_prop = p; /* Will show the popup */ if(prop_set_parent(p, prop_create(prop_get_global(), "popups"))) { /* popuproot is a zombie, this is an error */ abort(); } cs->cs_input_req_inv = inv; g_object_ref(G_OBJECT(inv)); return NULL; }
static void htsp_channelAddUpdate(htsp_connection_t *hc, htsmsg_t *m, int create) { uint32_t id, next; int chnum; char txt[200]; const char *title, *icon; htsp_channel_t *ch; if(htsmsg_get_u32(m, "channelId", &id)) return; title = htsmsg_get_str(m, "channelName"); icon = htsmsg_get_str(m, "channelIcon"); chnum = htsmsg_get_s32_or_default(m, "channelNumber", -1); snprintf(txt, sizeof(txt), "%d", id); hts_mutex_lock(&hc->hc_meta_mutex); if(create) { ch = htsp_channel_get(hc, id, 1); if(prop_set_parent(ch->ch_root, hc->hc_channels_nodes)) abort(); } else { ch = htsp_channel_get(hc, id, 0); if(ch == NULL) { TRACE(TRACE_ERROR, "HTSP", "Got update for unknown channel %d", id); hts_mutex_unlock(&hc->hc_meta_mutex); return; } } hts_mutex_unlock(&hc->hc_meta_mutex); if(icon != NULL) prop_set_string(ch->ch_prop_icon, icon); if(title != NULL) { mystrset(&ch->ch_title, title); prop_set_string(ch->ch_prop_title, title); } if(chnum != -1) prop_set_int(ch->ch_prop_channelNumber, chnum); if(htsmsg_get_u32(m, "eventId", &id)) id = 0; if(htsmsg_get_u32(m, "nextEventId", &next)) next = 0; update_events(hc, ch->ch_prop_events, id, next); }
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; }
/** * Consume 'locate' (updatedb) output results and feed into search results. */ static void fa_locate_searcher (fa_search_t *fas) { char buf[PATH_MAX]; char iconpath[PATH_MAX]; regex_t preg; prop_t *entries[2] = {NULL, NULL}; prop_t *nodes[2] = {NULL, NULL}; int t, i; if (fa_create_paths_regex(&preg) == -1) return fa_search_destroy(fas); snprintf(iconpath, sizeof(iconpath), "%s/resources/fileaccess/fs_icon.png", showtime_dataroot()); /* Consume 'locate' results. */ while (1) { char url[PATH_MAX+strlen("file://")]; prop_t *p, *metadata; const char *type; struct fa_stat fs; int ctype; prop_courier_poll(fas->fas_pc); if (!fas->fas_run) break; if (!fgets(buf, sizeof(buf), fas->fas_fp)) break; if (!*buf || *buf == '\n') continue; buf[strlen(buf)-1] = '\0'; /* Ignore dot-files/dirs. */ if (strstr(buf, "/.")) continue; if (regexec(&preg, buf, 0, NULL, 0)) { TRACE(TRACE_DEBUG, "FA", "Searcher: %s: \"%s\" not matching regex: SKIP", fas->fas_query, buf); continue; } /* Probe media type. * * FIXME: We might want to hide matching files under a matching directory, * or the other way around. * E..g: * Metallica/ * 01-Metallica-Song1.mp3 * 02-Metallica-Song1.mp3 * * Should either hide Metallica/ or 01-Metallica-Song1..2.. * But that would require the 'locate' output to be sorted, is it? * Its also problematic where a sub set of the tracks matches * the directory name. Then what should we show?. * * There is also the problem with: * Scrubs S01E01/ * Scrubs_s01e01.avi * Sample/ * Scrubs_s01e01_sample.avi * Which will show as four separate entries, less than optimal. * * For now we provide all matches, directories and files, * matching on the entire path (not just the basename). */ snprintf(url, sizeof(url), "file://%s", buf); if (fa_stat(url, &fs, NULL, 0)) continue; metadata = prop_create_root("metadata"); if(fs.fs_type == CONTENT_DIR) { ctype = CONTENT_DIR; prop_set_string(prop_create(metadata, "title"), basename(buf)); } else { metadata_t *md = fa_probe_metadata(url, NULL, 0); if(md != NULL) { ctype = md->md_contenttype; metadata_destroy(md); } else { ctype = CONTENT_UNKNOWN; } } if (ctype == CONTENT_UNKNOWN) continue; switch(ctype) { case CONTENT_AUDIO: t = 0; break; case CONTENT_VIDEO: case CONTENT_DVD: t = 1; break; default: continue; } if(nodes[t] == NULL) if(search_class_create(fas->fas_nodes, &nodes[t], &entries[t], t ? "Local video files" : "Local audio files", iconpath)) break; prop_add_int(entries[t], 1); if ((type = content2type(ctype)) == NULL) continue; /* Unlikely.. */ p = prop_create_root(NULL); if (prop_set_parent(metadata, p)) prop_destroy(metadata); prop_set_string(prop_create(p, "url"), url); prop_set_string(prop_create(p, "type"), type); if(prop_set_parent(p, nodes[t])) { prop_destroy(p); break; } } for(i = 0; i < 2; i++) { if(nodes[i]) prop_ref_dec(nodes[i]); if(entries[i]) prop_ref_dec(entries[i]); } TRACE(TRACE_DEBUG, "FA", "Searcher: %s: Done", fas->fas_query); fa_search_destroy(fas); regfree(&preg); }
static JSBool js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent, const char *url, const char *type, JSObject *metaobj, jsval *data, jsval *rval, int enabled, const char *metabind) { install_nodesub(model); prop_t *item = prop_create_root(NULL); rstr_t *rurl = url ? rstr_alloc(url) : NULL; if(url != NULL) prop_set(item, "url", PROP_SET_RSTRING, rurl); if(data != NULL) js_prop_set_from_jsval(cx, prop_create(item, "data"), *data); *rval = JSVAL_VOID; if(metabind != NULL) playinfo_bind_url_to_prop(metabind, item); if(type != NULL) { prop_set_string(prop_create(item, "type"), type); if(metaobj) js_prop_from_object(cx, metaobj, prop_create(item, "metadata")); } else if(url != NULL) { if(backend_resolve_item(url, item)) { prop_destroy(item); rstr_release(rurl); return JS_TRUE; } } prop_set_int(prop_create(item, "enabled"), enabled); prop_t *p = prop_ref_inc(item); if(prop_set_parent(item, parent)) { prop_destroy(item); prop_ref_dec(p); } else { JSObject *robj = JS_NewObjectWithGivenProto(cx, &item_class, JSVAL_TO_OBJECT(model->jm_item_proto), NULL); *rval = OBJECT_TO_JSVAL(robj); js_item_t *ji = calloc(1, sizeof(js_item_t)); atomic_add(&model->jm_refcount, 1); ji->ji_url = rstr_dup(rurl); ji->ji_model = model; ji->ji_root = p; TAILQ_INSERT_TAIL(&model->jm_items, ji, ji_link); JS_SetPrivate(cx, robj, ji); ji->ji_enable_set_property = 1; ji->ji_eventsub = prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, js_item_eventsub, ji, PROP_TAG_ROOT, ji->ji_root, PROP_TAG_COURIER, model->jm_pc, NULL); model->jm_subs++; ji->ji_this = OBJECT_TO_JSVAL(robj); JS_AddNamedRoot(cx, &ji->ji_this, "item_this"); prop_tag_set(ji->ji_root, model, ji); } rstr_release(rurl); return JS_TRUE; }
event_t * popup_display_kbrd(prop_t *p, prop_t *string) { prop_courier_t *pc = prop_courier_create_waitable(); event_t *e = NULL; prop_t *r = prop_create(p, "eventSink"); prop_sub_t *s = prop_subscribe(0, PROP_TAG_CALLBACK, eventsink, &e, PROP_TAG_ROOT, r, PROP_TAG_COURIER, pc, NULL); /* Will show the popup */ if(prop_set_parent(p, prop_create(prop_get_global(), "popups"))) { /* popuproot is a zombie, this is an error */ abort(); } while (e == NULL || (!event_is_action(e, ACTION_OK) && !event_is_action(e, ACTION_CANCEL))) { while(e == NULL) prop_courier_wait_and_dispatch(pc); if (!event_is_action(e, ACTION_OK) && !event_is_action(e, ACTION_CANCEL)) { char *tmpInput; htsmsg_t *m; rstr_t *r; m = htsmsg_create_map(); r = prop_get_string(string); htsmsg_add_str(m, "input", r ? rstr_get(r) : ""); rstr_release(r); htsmsg_get_str(m, "input"); setstr(&tmpInput, m, "input"); if (event_is_action(e, ACTION_KBRD_A)) strcat(tmpInput, "a"); else if (event_is_action(e, ACTION_KBRD_B)) strcat(tmpInput, "b"); else if (event_is_action(e, ACTION_KBRD_C)) strcat(tmpInput, "c"); else if (event_is_action(e, ACTION_KBRD_D)) strcat(tmpInput, "d"); else if (event_is_action(e, ACTION_KBRD_E)) strcat(tmpInput, "e"); else if (event_is_action(e, ACTION_KBRD_F)) strcat(tmpInput, "f"); else if (event_is_action(e, ACTION_KBRD_G)) strcat(tmpInput, "g"); else if (event_is_action(e, ACTION_KBRD_H)) strcat(tmpInput, "h"); else if (event_is_action(e, ACTION_KBRD_I)) strcat(tmpInput, "i"); else if (event_is_action(e, ACTION_KBRD_J)) strcat(tmpInput, "j"); else if (event_is_action(e, ACTION_KBRD_K)) strcat(tmpInput, "k"); else if (event_is_action(e, ACTION_KBRD_L)) strcat(tmpInput, "l"); else if (event_is_action(e, ACTION_KBRD_M)) strcat(tmpInput, "m"); else if (event_is_action(e, ACTION_KBRD_N)) strcat(tmpInput, "n"); else if (event_is_action(e, ACTION_KBRD_O)) strcat(tmpInput, "o"); else if (event_is_action(e, ACTION_KBRD_P)) strcat(tmpInput, "p"); else if (event_is_action(e, ACTION_KBRD_Q)) strcat(tmpInput, "q"); else if (event_is_action(e, ACTION_KBRD_R)) strcat(tmpInput, "r"); else if (event_is_action(e, ACTION_KBRD_S)) strcat(tmpInput, "s"); else if (event_is_action(e, ACTION_KBRD_T)) strcat(tmpInput, "t"); else if (event_is_action(e, ACTION_KBRD_U)) strcat(tmpInput, "u"); else if (event_is_action(e, ACTION_KBRD_V)) strcat(tmpInput, "v"); else if (event_is_action(e, ACTION_KBRD_W)) strcat(tmpInput, "w"); else if (event_is_action(e, ACTION_KBRD_X)) strcat(tmpInput, "x"); else if (event_is_action(e, ACTION_KBRD_Y)) strcat(tmpInput, "y"); else if (event_is_action(e, ACTION_KBRD_Z)) strcat(tmpInput, "z"); else if (event_is_action(e, ACTION_KBRD_0)) strcat(tmpInput, "0"); else if (event_is_action(e, ACTION_KBRD_1)) strcat(tmpInput, "1"); else if (event_is_action(e, ACTION_KBRD_2)) strcat(tmpInput, "2"); else if (event_is_action(e, ACTION_KBRD_3)) strcat(tmpInput, "3"); else if (event_is_action(e, ACTION_KBRD_4)) strcat(tmpInput, "4"); else if (event_is_action(e, ACTION_KBRD_5)) strcat(tmpInput, "5"); else if (event_is_action(e, ACTION_KBRD_6)) strcat(tmpInput, "6"); else if (event_is_action(e, ACTION_KBRD_7)) strcat(tmpInput, "7"); else if (event_is_action(e, ACTION_KBRD_8)) strcat(tmpInput, "8"); else if (event_is_action(e, ACTION_KBRD_9)) strcat(tmpInput, "9"); else if (event_is_action(e, ACTION_KBRD_COMMA)) strcat(tmpInput, ","); else if (event_is_action(e, ACTION_KBRD_DOT)) strcat(tmpInput, "."); else if (event_is_action(e, ACTION_KBRD_SPACE)) strcat(tmpInput, " "); else if (event_is_action(e, ACTION_BS)) { if (strlen(tmpInput) > 0) { strncpy(tmpInput, tmpInput, strlen(tmpInput) - 1); tmpInput[strlen(tmpInput) - 1] = '\0'; } } prop_set_string(string, tmpInput); e = NULL; } } prop_unsubscribe(s); return e; }