int message_popup(const char *message, int flags) { prop_t *p; int rval; p = prop_create_root(NULL); 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(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); if(event_is_action(e, ACTION_OK)) rval = MESSAGE_POPUP_OK; else if(event_is_action(e, ACTION_CANCEL)) rval = MESSAGE_POPUP_CANCEL; else rval = 0; event_release(e); return rval; }
static event_t * rtmp_process_event(rtmp_t *r, event_t *e, media_buf_t **mbp) { media_pipe_t *mp = r->mp; if(event_is_type(e, EVENT_EXIT) || event_is_type(e, EVENT_PLAY_URL) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_SKIP_BACKWARD)) return e; if(event_is_type(e, EVENT_CURRENT_TIME)) { event_ts_t *ets = (event_ts_t *)e; int sec = ets->ts / 1000000; if(sec != r->restartpos_last && mp->mp_flags & MP_CAN_SEEK) { r->restartpos_last = sec; playinfo_set_restartpos(r->canonical_url, mp->mp_seek_base / 1000, 1); } } else if(mp->mp_flags & MP_CAN_SEEK && event_is_type(e, EVENT_SEEK)) { event_ts_t *ets = (event_ts_t *)e; video_seek(r, mp, mbp, ets->ts, "direct"); } event_release(e); return NULL; }
static void nav_eventsink(void *opaque, prop_event_t event, ...) { navigator_t *nav = opaque; event_t *e; event_openurl_t *ou; va_list ap; va_start(ap, event); if(event != PROP_EXT_EVENT) return; e = va_arg(ap, event_t *); if(event_is_action(e, ACTION_NAV_BACK)) { nav_back(nav); } else if(event_is_action(e, ACTION_NAV_FWD)) { nav_fwd(nav); } else if(event_is_action(e, ACTION_HOME)) { nav_open0(nav, NAV_HOME, NULL, NULL); } else if(event_is_type(e, EVENT_OPENURL)) { ou = (event_openurl_t *)e; nav_open0(nav, ou->url, ou->view, ou->origin); } }
static void nav_eventsink(void *opaque, prop_event_t event, ...) { navigator_t *nav = opaque; event_t *e; event_openurl_t *ou; va_list ap; va_start(ap, event); if(event != PROP_EXT_EVENT) return; e = va_arg(ap, event_t *); if(event_is_action(e, ACTION_NAV_BACK)) { nav_back(nav); } else if(event_is_action(e, ACTION_NAV_FWD)) { nav_fwd(nav); } else if(event_is_action(e, ACTION_HOME)) { nav_open0(nav, NAV_HOME, NULL, NULL); } else if(event_is_action(e, ACTION_RELOAD_DATA)) { nav_reload_current(nav); } else if(event_is_type(e, EVENT_OPENURL)) { ou = (event_openurl_t *)e; if(ou->url != NULL) nav_open0(nav, ou->url, ou->view, ou->origin); else TRACE(TRACE_INFO, "Navigator", "Tried to open NULL URL"); } }
int glw_navigate_horizontal(struct glw *w, struct event *e) { glw_t *c = w->glw_focused; const int may_wrap = glw_navigate_may_wrap(w); if(c == NULL) return 0; if(event_is_action(e, ACTION_LEFT)) { return glw_navigate_step(c, -1, may_wrap); } else if(event_is_action(e, ACTION_RIGHT)) { return glw_navigate_step(c, 1, may_wrap); } else if(event_is_action(e, ACTION_MOVE_RIGHT)) { return glw_navigate_move(c, 1); } else if(event_is_action(e, ACTION_MOVE_LEFT)) { return glw_navigate_move(c, -1); } return 0; }
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; }
int action_update_hold_by_event(int hold, event_t *e) { if(event_is_action(e, ACTION_PLAYPAUSE)) return !hold; if(event_is_action(e, ACTION_PAUSE)) return 1; if(event_is_action(e, ACTION_PLAY)) return 0; return 0; }
static int glw_slider_event_x(glw_t *w, event_t *e) { glw_slider_t *s = (glw_slider_t *)w; float d; if(event_is_action(e, ACTION_LEFT)) { d = -s->step_i; } else if(event_is_action(e, ACTION_RIGHT)) { d = s->step_i; } else { return 0; } update_value_delta(s, d); return 1; }
static event_t * be_dvd_play(struct backend *be, const char *url, media_pipe_t *mp, int flags, int priority, char *errstr, size_t errlen) { event_t *e; int i; if(strcmp(url, "dvd:/dev/di")) { snprintf(errstr, errlen, "dvd: Invalid URL"); return NULL; } for(i = 0; i < 20; i++) { if(DI_GetStatus() & DVD_READY) break; sleep(1); } e = dvd_play("/dev/di", mp, errstr, errlen, 0); if(e != NULL && event_is_action(e, ACTION_EJECT)) DI_Eject(); return e; }
static int ki_handle_event(glw_keyintercept_t *ki, event_t *e) { if(event_is_action(e, ACTION_BS)) { if(ki->buflen == 0) return 0; ki->buflen--; updatestr(ki); return 1; } if(event_is_type(e, EVENT_UNICODE)) { event_int_t *ei = (event_int_t *)e; int c = ei->val; if(c == 32 && ki->buflen == 0) return 0; // space as first char is not something we trig on if(ki->buflen == KI_BUF_LEN - 1) return 1; ki->buf[ki->buflen] = c; ki->buflen++; updatestr(ki); return 1; } return 0; }
static event_t * be_dvd_play(const char *url, media_pipe_t *mp, char *errstr, size_t errlen, struct video_queue *vq, struct vsource_list *vsl, const video_args_t *va) { event_t *e; if(strncmp(url, "dvd:", strlen("dvd:"))) { snprintf(errstr, errlen, "dvd: Invalid URL"); return NULL; } url += 4; mp_set_url(mp, va->canonical_url, va->parent_url, va->parent_title); e = dvd_play(url, mp, errstr, errlen, 0); if(e != NULL && event_is_action(e, ACTION_EJECT)) { int fd = open(url, O_RDONLY | O_NONBLOCK); if(fd != -1) { if(ioctl(fd, CDROMEJECT, NULL)) TRACE(TRACE_ERROR, "DVD", "Eject of %s failed -- %s", url, strerror(errno)); close(fd); } else { TRACE(TRACE_ERROR, "DVD", "Unable to open %s for eject -- %s", url, strerror(errno)); } } return e; }
static event_t * be_dvd_play(const char *url, media_pipe_t *mp, int flags, int priority, char *errstr, size_t errlen, const char *mimetype, const char *canonical_url) { event_t *e; if(strncmp(url, "dvd:", strlen("dvd:"))) { snprintf(errstr, errlen, "dvd: Invalid URL"); return NULL; } url += 4; e = dvd_play(url, mp, errstr, errlen, 0); if(e != NULL && event_is_action(e, ACTION_EJECT)) { int fd = open(url, O_RDONLY | O_NONBLOCK); if(fd != -1) { if(ioctl(fd, CDROMEJECT, NULL)) TRACE(TRACE_ERROR, "DVD", "Eject of %s failed -- %s", url, strerror(errno)); close(fd); } else { TRACE(TRACE_ERROR, "DVD", "Unable to open %s for eject -- %s", url, strerror(errno)); } } return e; }
static event_t * rtmp_process_event(rtmp_t *r, event_t *e, media_buf_t **mbp) { media_pipe_t *mp = r->mp; if(event_is_type(e, EVENT_EXIT) || event_is_type(e, EVENT_PLAY_URL) || event_is_action(e, ACTION_SKIP_FORWARD)) return e; if(event_is_action(e, ACTION_SKIP_BACKWARD)) { if(mp->mp_seek_base < MP_SKIP_LIMIT) { return e; } video_seek(r, mp, mbp, 0, "direct"); } if(event_is_type(e, EVENT_CURRENT_TIME)) { event_ts_t *ets = (event_ts_t *)e; int sec = ets->ts / 1000000; if(sec != r->restartpos_last && r->can_seek) { r->restartpos_last = sec; metadb_set_video_restartpos(r->canonical_url, mp->mp_seek_base / 1000); } } else if(r->can_seek && event_is_type(e, EVENT_SEEK)) { event_ts_t *ets = (event_ts_t *)e; video_seek(r, mp, mbp, ets->ts, "direct"); } else if(event_is_action(e, ACTION_STOP)) { mp_set_playstatus_stop(mp); } else if(event_is_type(e, EVENT_SELECT_SUBTITLE_TRACK)) { event_select_track_t *est = (event_select_track_t *)e; prop_set_string(mp->mp_prop_subtitle_track_current, est->id); if(!strcmp(est->id, "sub:off")) { mp_load_ext_sub(mp, NULL); } else { mp_load_ext_sub(mp, est->id); } } event_release(e); return NULL; }
static int glw_slider_event_y(glw_t *w, event_t *e) { glw_slider_t *s = (glw_slider_t *)w; float d; if(event_is_action(e, ACTION_UP)) { d = -s->step; } else if(event_is_action(e, ACTION_DOWN)) { d = s->step; } else { return 0; } update_value_delta(s, d); return 1; }
int text_dialog_kbrd(const char *message, char** answer, int flags) { htsmsg_t *m; rstr_t *r; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "textDialogKbrd"); prop_set_string_ex(prop_create(p, "message"), NULL, message, flags & MESSAGE_POPUP_RICH_TEXT ? PROP_STR_RICH : PROP_STR_UTF8); prop_t *string = prop_create(p, "input"); 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_kbrd(p, string); if (event_is_action(e, ACTION_OK)) { 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(answer, m, "input"); } prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)){ event_release(e); return -1; } event_release(e); return 0; }
static void input_req_event(void *opaque, event_t *e) { connman_service_t *cs = opaque; if(cs->cs_input_req_inv == NULL) return; if(event_is_action(e, ACTION_OK)) { rstr_t *username = prop_get_string(cs->cs_input_req_prop, "username", NULL); rstr_t *password = prop_get_string(cs->cs_input_req_prop, "password", NULL); GVariant *result; GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(builder, "{sv}", "Passphrase", g_variant_new_string(rstr_get(password))); if(cs->cs_input_req_want_identity) g_variant_builder_add(builder, "{sv}", "Identity", g_variant_new_string(rstr_get(username))); result = g_variant_new("(a{sv})", builder); TRACE(TRACE_DEBUG, "CONNMAN", "Auth response: %s", g_variant_print(result, TRUE)); g_dbus_method_invocation_return_value(cs->cs_input_req_inv, result); g_variant_builder_unref(builder); rstr_release(username); rstr_release(password); connman_stop_input_request(cs); } if(event_is_action(e, ACTION_CANCEL)) { g_dbus_method_invocation_return_dbus_error(cs->cs_input_req_inv, "net.connman.Agent.Error.Canceled", "Canceled by user"); connman_stop_input_request(cs); } }
static int top_event_handler(glw_t *w, void *opaque, glw_signal_t sig, void *extra) { event_t *e = extra; glw_root_t *gr = opaque; if(sig != GLW_SIGNAL_EVENT_BUBBLE) return 0; if(e->e_type_x == EVENT_KEYDESC) return 0; if(event_is_action(e, ACTION_ENABLE_SCREENSAVER)) { gr->gr_screensaver_force_enable = 1; } else if(event_is_action(e, ACTION_NAV_BACK) || event_is_action(e, ACTION_NAV_FWD) || event_is_action(e, ACTION_HOME) || event_is_action(e, ACTION_PLAYQUEUE) || event_is_action(e, ACTION_RELOAD_DATA) || event_is_type(e, EVENT_OPENURL)) { prop_t *p = prop_get_by_name(PNVEC("nav", "eventsink"), 0, PROP_TAG_ROOT, gr->gr_prop_nav, NULL); prop_send_ext_event(p, e); prop_ref_dec(p); } else { event_addref(e); event_dispatch(e); } return 1; }
int text_dialog(const char *message, char **answer, int flags) { rstr_t *r; *answer = NULL; prop_t *p = prop_ref_inc(prop_create_root(NULL)); prop_set_string(prop_create(p, "type"), "textDialog"); prop_set_string_ex(prop_create(p, "message"), NULL, message, flags & MESSAGE_POPUP_RICH_TEXT ? PROP_STR_RICH : PROP_STR_UTF8); prop_t *string = prop_create(p, "input"); 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); if(event_is_action(e, ACTION_OK)) { r = prop_get_string(string, NULL); if(r) *answer = strdup(rstr_get(r)); rstr_release(r); } prop_destroy(p); prop_ref_dec(p); if(event_is_action(e, ACTION_CANCEL)) { event_release(e); return -1; } event_release(e); return 0; }
static int glw_slideshow_event(glw_t *w, event_t *e) { glw_root_t *gr = w->glw_root; glw_slideshow_t *s = (glw_slideshow_t *)w; glw_t *c; event_int_t *eu = (event_int_t *)e; if(event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_RIGHT)) { c = w->glw_focused ? glw_next_widget(w->glw_focused) : NULL; if(c == NULL) c = glw_first_widget(w); w->glw_focused = c; s->deadline = 0; glw_need_refresh(gr, 0); } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_LEFT)) { c = w->glw_focused ? glw_prev_widget(w->glw_focused) : NULL; if(c == NULL) c = glw_last_widget(w, 0); w->glw_focused = c; s->deadline = 0; glw_need_refresh(gr, 0); } else if(event_is_type(e, EVENT_UNICODE) && eu->val == 32) { s->hold = !s->hold; glw_slideshow_update_playstatus(s); } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { s->hold = action_update_hold_by_event(s->hold, e); glw_slideshow_update_playstatus(s); } else if(event_is_action(e, ACTION_STOP)) { prop_set_string(s->playstatus, "stop"); } else return 0; return 1; }
static int top_event_handler(glw_t *w, void *opaque, glw_signal_t sig, void *extra) { event_t *e = extra; glw_root_t *gr = opaque; if(sig != GLW_SIGNAL_EVENT_BUBBLE) return 0; if(e->e_type_x == EVENT_KEYDESC) return 0; if(event_is_action(e, ACTION_ENABLE_SCREENSAVER)) { gr->gr_screensaver_force_enable = 1; } else { event_addref(e); event_dispatch(e); } return 1; }
int glw_navigate_vertical(struct glw *w, struct event *e) { glw_t *c = w->glw_focused; if(c == NULL) return 0; const int may_wrap = glw_navigate_may_wrap(w); if(event_is_action(e, ACTION_DOWN)) { return glw_navigate_step(c, 1, may_wrap); } else if(event_is_action(e, ACTION_UP)) { return glw_navigate_step(c, -1, may_wrap); } else if(event_is_action(e, ACTION_PAGE_UP)) { return glw_navigate_step(c, -10, 0); } else if(event_is_action(e, ACTION_PAGE_DOWN)) { return glw_navigate_step(c, 10, 0); } else if(event_is_action(e, ACTION_TOP)) { return glw_nav_first(w); } else if(event_is_action(e, ACTION_BOTTOM)) { return glw_nav_last(w); } else if(event_is_action(e, ACTION_MOVE_DOWN)) { return glw_navigate_move(c, 1); } else if(event_is_action(e, ACTION_MOVE_UP)) { return glw_navigate_move(c, -1); } return 0; }
static event_t * openspc_play(media_pipe_t *mp, AVIOContext *avio, char *errbuf, size_t errlen) { media_queue_t *mq = &mp->mp_audio; #error fa_fsize can return -1 .. deal with it size_t r, siz = fa_fsize(fh); uint8_t *buf = malloc(siz); media_buf_t *mb = NULL; event_t *e; int hold = 0, lost_focus = 0; int sample = 0; unsigned int duration = INT32_MAX; mp_set_playstatus_by_hold(mp, hold, NULL); mp->mp_audio.mq_stream = 0; fa_seek(fh, 0, SEEK_SET); r = fa_read(fh, buf, siz); fa_close(fh); if(r != siz) { free(buf); snprintf(errbuf, errlen, "openspc: Unable to read file"); return NULL; } if(OSPC_Init(buf, siz)) { free(buf); snprintf(errbuf, errlen, "openspc: Unable to initialize file"); return NULL; } if(!memcmp("v0.30", buf + 0x1c, 4) && buf[0x23] == 0x1a) { char str[4]; memcpy(str, buf + 0xa9, 3); str[3] = 0; duration = atoi(str) * 32000; } mp_set_play_caps(mp, MP_PLAY_CAPS_PAUSE); mp_become_primary(mp); while(1) { if(mb == NULL) { if(sample > duration) { while((e = mp_wait_for_empty_queues(mp, 0)) != NULL) { if(event_is_type(e, EVENT_PLAYQUEUE_JUMP) || event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } if(e == NULL) e = event_create_type(EVENT_EOF); break; } mb = media_buf_alloc(); mb->mb_data_type = MB_AUDIO; mb->mb_size = sizeof(int16_t) * 2048 * 2; mb->mb_data = malloc(mb->mb_size); mb->mb_size = OSPC_Run(-1, mb->mb_data, mb->mb_size); mb->mb_channels = 2; mb->mb_rate = 32000; mb->mb_time = sample * 1000000LL / mb->mb_rate; sample += 2048; } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { hold = action_update_hold_by_event(hold, e); mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY); lost_focus = 0; mp_set_playstatus_by_hold(mp, hold, NULL); } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) { hold = 1; lost_focus = 1; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) { if(lost_focus) { hold = 0; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, hold, NULL); } } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) { hold = 1; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } free(buf); return e; }
event_t * be_file_playaudio(const char *url, media_pipe_t *mp, char *errbuf, size_t errlen, int hold, const char *mimetype) { AVFormatContext *fctx; AVCodecContext *ctx; AVPacket pkt; media_format_t *fw; int i, r, si; media_buf_t *mb = NULL; media_queue_t *mq; event_ts_t *ets; int64_t ts, seekbase = 0; media_codec_t *cw; event_t *e; int lost_focus = 0; int registered_play = 0; mp_set_playstatus_by_hold(mp, hold, NULL); fa_handle_t *fh = fa_open_ex(url, errbuf, errlen, FA_BUFFERED_SMALL, NULL); if(fh == NULL) return NULL; // First we need to check for a few other formats #if ENABLE_LIBOPENSPC || ENABLE_LIBGME uint8_t pb[128]; size_t psiz; psiz = fa_read(fh, pb, sizeof(pb)); if(psiz < sizeof(pb)) { fa_close(fh); snprintf(errbuf, errlen, "Fill too small"); return NULL; } #if ENABLE_LIBGME if(*gme_identify_header(pb)) return fa_gme_playfile(mp, fh, errbuf, errlen, hold, url); #endif #if ENABLE_LIBOPENSPC if(!memcmp(pb, "SNES-SPC700 Sound File Data", 27)) return openspc_play(mp, fh, errbuf, errlen); #endif #endif AVIOContext *avio = fa_libav_reopen(fh); if(avio == NULL) { fa_close(fh); return NULL; } if((fctx = fa_libav_open_format(avio, url, errbuf, errlen, mimetype)) == NULL) { fa_libav_close(avio); return NULL; } TRACE(TRACE_DEBUG, "Audio", "Starting playback of %s", url); mp_configure(mp, MP_PLAY_CAPS_SEEK | MP_PLAY_CAPS_PAUSE, MP_BUFFER_SHALLOW); mp->mp_audio.mq_stream = -1; mp->mp_video.mq_stream = -1; fw = media_format_create(fctx); cw = NULL; for(i = 0; i < fctx->nb_streams; i++) { ctx = fctx->streams[i]->codec; if(ctx->codec_type != AVMEDIA_TYPE_AUDIO) continue; cw = media_codec_create(ctx->codec_id, 0, fw, ctx, NULL, mp); mp->mp_audio.mq_stream = i; break; } if(cw == NULL) { media_format_deref(fw); snprintf(errbuf, errlen, "Unable to open codec"); return NULL; } mp_become_primary(mp); mq = &mp->mp_audio; while(1) { /** * Need to fetch a new packet ? */ if(mb == NULL) { mp->mp_eof = 0; r = av_read_frame(fctx, &pkt); if(r == AVERROR(EAGAIN)) continue; if(r == AVERROR_EOF || r == AVERROR(EIO)) { mb = MB_SPECIAL_EOF; mp->mp_eof = 1; continue; } if(r != 0) { char msg[100]; fa_ffmpeg_error_to_txt(r, msg, sizeof(msg)); TRACE(TRACE_ERROR, "Audio", "Playback error: %s", msg); while((e = mp_wait_for_empty_queues(mp)) != NULL) { if(event_is_type(e, EVENT_PLAYQUEUE_JUMP) || event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } if(e == NULL) e = event_create_type(EVENT_EOF); break; } si = pkt.stream_index; if(si != mp->mp_audio.mq_stream) { av_free_packet(&pkt); continue; } mb = media_buf_alloc_unlocked(mp, pkt.size); mb->mb_data_type = MB_AUDIO; mb->mb_pts = rescale(fctx, pkt.pts, si); mb->mb_dts = rescale(fctx, pkt.dts, si); mb->mb_duration = rescale(fctx, pkt.duration, si); mb->mb_cw = media_codec_ref(cw); /* Move the data pointers from ffmpeg's packet */ mb->mb_stream = pkt.stream_index; memcpy(mb->mb_data, pkt.data, pkt.size); if(mb->mb_pts != AV_NOPTS_VALUE) { if(fctx->start_time == AV_NOPTS_VALUE) mb->mb_time = mb->mb_pts; else mb->mb_time = mb->mb_pts - fctx->start_time; } else mb->mb_time = AV_NOPTS_VALUE; mb->mb_send_pts = 1; av_free_packet(&pkt); } /* * Try to send the buffer. If mb_enqueue() returns something we * catched an event instead of enqueueing the buffer. In this case * 'mb' will be left untouched. */ if(mb == MB_SPECIAL_EOF) { // We have reached EOF, drain queues e = mp_wait_for_empty_queues(mp); if(e == NULL) { e = event_create_type(EVENT_EOF); break; } } else if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_type(e, EVENT_CURRENT_PTS)) { ets = (event_ts_t *)e; seekbase = ets->ts; if(registered_play == 0) { if(ets->ts - fctx->start_time > METADB_AUDIO_PLAY_THRESHOLD) { registered_play = 1; metadb_register_play(url, 1, CONTENT_AUDIO); } } } else if(event_is_type(e, EVENT_SEEK)) { ets = (event_ts_t *)e; ts = ets->ts + fctx->start_time; if(ts < fctx->start_time) ts = fctx->start_time; av_seek_frame(fctx, -1, ts, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) { av_seek_frame(fctx, -1, seekbase - 60000000, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) { av_seek_frame(fctx, -1, seekbase - 15000000, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) { av_seek_frame(fctx, -1, seekbase + 60000000, 0); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FORWARD)) { av_seek_frame(fctx, -1, seekbase + 15000000, 0); seekflush(mp, &mb); #if 0 } else if(event_is_action(e, ACTION_RESTART_TRACK)) { av_seek_frame(fctx, -1, 0, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); #endif } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { hold = action_update_hold_by_event(hold, e); mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY); lost_focus = 0; mp_set_playstatus_by_hold(mp, hold, NULL); } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) { hold = 1; lost_focus = 1; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) { if(lost_focus) { hold = 0; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, hold, NULL); } } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) { hold = 1; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } if(mb != NULL && mb != MB_SPECIAL_EOF) media_buf_free_unlocked(mp, mb); media_codec_deref(cw); media_format_deref(fw); if(hold) { // If we were paused, release playback again. mp_send_cmd(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, 0, NULL); } return e; }
static int glw_text_bitmap_event(glw_t *w, event_t *e) { glw_text_bitmap_t *gtb = (glw_text_bitmap_t *)w; if(event_is_action(e, ACTION_BS)) { del_char(gtb); gtb_notify(gtb); return 1; } else if(event_is_type(e, EVENT_UNICODE)) { event_int_t *eu = (event_int_t *)e; if(insert_char(gtb, eu->val)) gtb_notify(gtb); return 1; } else if(event_is_type(e, EVENT_INSERT_STRING)) { event_payload_t *ep = (event_payload_t *)e; const char *str = ep->payload; int uc; while((uc = utf8_get(&str)) != 0) { insert_char(gtb, uc); } gtb_notify(gtb); return 1; } else if(event_is_action(e, ACTION_LEFT)) { if(gtb->gtb_edit_ptr > 0) { gtb->gtb_edit_ptr--; gtb->gtb_update_cursor = 1; } return 1; } else if(event_is_action(e, ACTION_RIGHT)) { if(gtb->gtb_edit_ptr < gtb->gtb_uc_len) { gtb->gtb_edit_ptr++; gtb->gtb_update_cursor = 1; } return 1; } else if(event_is_action(e, ACTION_ACTIVATE) || event_is_action(e, ACTION_ITEMMENU)) { gtb_caption_refresh(gtb); if(gtb->gtb_flags & (GTB_FILE_REQUEST | GTB_DIR_REQUEST)) { if(gtb->gtb_p == NULL) { TRACE(TRACE_ERROR, "GLW", "File requests on unbound widgets is not supported"); } else { int flags = (gtb->gtb_flags & GTB_FILE_REQUEST ? FILEPICKER_FILES : 0) | (gtb->gtb_flags & GTB_DIR_REQUEST ? FILEPICKER_DIRECTORIES : 0); filepicker_pick_to_prop(gtb->gtb_description, gtb->gtb_p, gtb->gtb_caption, flags); } } else { if(event_is_action(e, ACTION_ACTIVATE) && e->e_flags & EVENT_MOUSE) return 1; w->glw_root->gr_open_osk(w->glw_root, gtb->gtb_description, gtb->gtb_caption, w, gtb->gtb_flags & GTB_PASSWORD); } return 1; } return 0; }
event_t * fa_xmp_playfile(media_pipe_t *mp, FILE *f, char *errbuf, size_t errlen, int hold, const char *url, size_t size) { event_t *e = NULL; xmp_context ctx = xmp_create_context(); // struct xmp_module_info mi; struct xmp_frame_info fi; char *u = mystrdupa(url); mp->mp_audio.mq_stream = 0; mp_configure(mp, MP_CAN_PAUSE | MP_CAN_SEEK, MP_BUFFER_SHALLOW, 0, "tracks"); mp_become_primary(mp); if(xmp_load_modulef(ctx, f, u, size) >= 0) { if(xmp_start_player(ctx, 44100, 0) == 0) { media_buf_t *mb = NULL; media_queue_t *mq = &mp->mp_audio; while(1) { if(mb == NULL) { if(xmp_play_frame(ctx)) { e = event_create_type(EVENT_EOF); break; } xmp_get_frame_info(ctx, &fi); if(fi.loop_count > 0) { e = event_create_type(EVENT_EOF); break; } mb = media_buf_alloc_unlocked(mp, fi.buffer_size); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_rate = 44100; mb->mb_pts = fi.time * 1000; mb->mb_drive_clock = 1; memcpy(mb->mb_data, fi.buffer, fi.buffer_size); mp_set_duration(mp, fi.total_time * 1000); } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } xmp_end_player(ctx); } else { snprintf(errbuf, errlen, "XMP failed to start"); } } else { snprintf(errbuf, errlen, "XMP Loading error"); } // prop_ref_dec(dur); xmp_free_context(ctx); return e; }
event_t * be_file_playaudio(const char *url, media_pipe_t *mp, char *errbuf, size_t errlen, int hold) { AVFormatContext *fctx; AVIOContext *avio; AVCodecContext *ctx; AVPacket pkt; media_format_t *fw; int i, r, si; media_buf_t *mb = NULL; media_queue_t *mq; event_ts_t *ets; int64_t ts, pts4seek = 0; media_codec_t *cw; event_t *e; int lost_focus = 0; mp_set_playstatus_by_hold(mp, hold, NULL); if((avio = fa_libav_open(url, 32768, errbuf, errlen)) == NULL) return NULL; // First we need to check for a few other formats #if ENABLE_LIBOPENSPC || ENABLE_LIBGME uint8_t pb[128]; size_t psiz; psiz = avio_read(avio, pb, sizeof(pb)); if(psiz < sizeof(pb)) { fa_libav_close(avio); snprintf(errbuf, errlen, "Fill too small"); return NULL; } #if ENABLE_LIBGME if(*gme_identify_header(pb)) return fa_gme_playfile(mp, avio, errbuf, errlen, hold); #endif #if ENABLE_LIBOPENSPC if(!memcmp(pb, "SNES-SPC700 Sound File Data", 27)) return openspc_play(mp, avio, errbuf, errlen); #endif #endif if((fctx = fa_libav_open_format(avio, url, errbuf, errlen)) == NULL) { fa_libav_close(avio); return NULL; } TRACE(TRACE_DEBUG, "Audio", "Starting playback of %s", url); mp_set_play_caps(mp, MP_PLAY_CAPS_SEEK | MP_PLAY_CAPS_PAUSE); mp->mp_audio.mq_stream = -1; mp->mp_video.mq_stream = -1; fw = media_format_create(fctx); cw = NULL; for(i = 0; i < fctx->nb_streams; i++) { ctx = fctx->streams[i]->codec; if(ctx->codec_type != AVMEDIA_TYPE_AUDIO) continue; cw = media_codec_create(ctx->codec_id, 0, fw, ctx, NULL, mp); mp->mp_audio.mq_stream = i; break; } if(cw == NULL) { media_format_deref(fw); snprintf(errbuf, errlen, "Unable to open codec"); return NULL; } mp_become_primary(mp); mq = &mp->mp_audio; while(1) { /** * Need to fetch a new packet ? */ if(mb == NULL) { if((r = av_read_frame(fctx, &pkt)) < 0) { while((e = mp_wait_for_empty_queues(mp, 0)) != NULL) { if(event_is_type(e, EVENT_PLAYQUEUE_JUMP) || event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } if(e == NULL) e = event_create_type(EVENT_EOF); break; } si = pkt.stream_index; if(si == mp->mp_audio.mq_stream) { /* Current audio stream */ mb = media_buf_alloc(); mb->mb_data_type = MB_AUDIO; } else { /* Check event queue ? */ av_free_packet(&pkt); continue; } mb->mb_pts = rescale(fctx, pkt.pts, si); mb->mb_dts = rescale(fctx, pkt.dts, si); mb->mb_duration = rescale(fctx, pkt.duration, si); mb->mb_cw = media_codec_ref(cw); /* Move the data pointers from ffmpeg's packet */ mb->mb_stream = pkt.stream_index; av_dup_packet(&pkt); mb->mb_data = pkt.data; pkt.data = NULL; mb->mb_size = pkt.size; pkt.size = 0; if(mb->mb_pts != AV_NOPTS_VALUE) { if(fctx->start_time == AV_NOPTS_VALUE) mb->mb_time = mb->mb_pts; else mb->mb_time = mb->mb_pts - fctx->start_time; pts4seek = mb->mb_time; } else mb->mb_time = AV_NOPTS_VALUE; av_free_packet(&pkt); } /* * Try to send the buffer. If mb_enqueue() returns something we * catched an event instead of enqueueing the buffer. In this case * 'mb' will be left untouched. */ if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_type(e, EVENT_SEEK)) { ets = (event_ts_t *)e; ts = ets->pts + fctx->start_time; if(ts < fctx->start_time) ts = fctx->start_time; av_seek_frame(fctx, -1, ts, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) { av_seek_frame(fctx, -1, pts4seek - 60000000, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) { av_seek_frame(fctx, -1, pts4seek - 15000000, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) { av_seek_frame(fctx, -1, pts4seek + 60000000, 0); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FORWARD)) { av_seek_frame(fctx, -1, pts4seek + 15000000, 0); seekflush(mp, &mb); #if 0 } else if(event_is_action(e, ACTION_RESTART_TRACK)) { av_seek_frame(fctx, -1, 0, AVSEEK_FLAG_BACKWARD); seekflush(mp, &mb); #endif } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { hold = action_update_hold_by_event(hold, e); mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY); lost_focus = 0; mp_set_playstatus_by_hold(mp, hold, NULL); } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) { hold = 1; lost_focus = 1; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) { if(lost_focus) { hold = 0; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, hold, NULL); } } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) { hold = 1; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } if(mb != NULL) media_buf_free(mb); media_codec_deref(cw); media_format_deref(fw); if(hold) { // If we were paused, release playback again. mp_send_cmd(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, 0, NULL); } return e; }
static event_t * fa_gme_playfile_internal(media_pipe_t *mp, const void *buf, size_t size, char *errbuf, size_t errlen, int hold, int track, const char *url) { media_queue_t *mq = &mp->mp_audio; Music_Emu *emu; gme_err_t err; int sample_rate = 48000; media_buf_t *mb = NULL; event_t *e; int registered_play = 0; err = gme_open_data(buf, size, &emu, sample_rate); if(err != NULL) { snprintf(errbuf, errlen, "Unable to load file -- %s", err); return NULL; } gme_start_track(emu, track); mp->mp_audio.mq_stream = 0; mp_configure(mp, MP_PLAY_CAPS_PAUSE | MP_PLAY_CAPS_SEEK, MP_BUFFER_SHALLOW, 0); mp_become_primary(mp); while(1) { if(gme_track_ended(emu)) { e = event_create_type(EVENT_EOF); break; } if(mb == NULL) { mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_rate = sample_rate; mb->mb_pts = gme_tell(emu) * 1000; mb->mb_drive_clock = 1; if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) { registered_play = 1; metadb_register_play(url, 1, CONTENT_AUDIO); } gme_play(emu, CHUNK_SIZE * mb->mb_channels, mb->mb_data); } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_type(e, EVENT_SEEK)) { event_ts_t *ets = (event_ts_t *)e; gme_seek(emu, ets->ts / 1000); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } gme_delete(emu); if(mb != NULL) media_buf_free_unlocked(mp, mb); return e; }
void event_dispatch(event_t *e) { prop_t *p; event_int_t *eu = (event_int_t *)e; if(event_is_type(e, EVENT_UNICODE) && eu->val == 32) { // Convert [space] into playpause event_release(e); e = event_create_action(ACTION_PLAYPAUSE); } event_to_prop(prop_get_by_name(PNVEC("global", "eventsink"), 1, NULL), e); if(event_is_action(e, ACTION_QUIT)) { showtime_shutdown(0); } else if(event_is_action(e, ACTION_STANDBY)) { showtime_shutdown(10); } else if(event_is_action(e, ACTION_POWER_OFF)) { showtime_shutdown(11); } else if(event_is_action(e, ACTION_NAV_BACK) || event_is_action(e, ACTION_NAV_FWD) || event_is_action(e, ACTION_HOME) || event_is_action(e, ACTION_RELOAD_DATA) || event_is_type(e, EVENT_OPENURL)) { event_to_prop(prop_get_by_name(PNVEC("global", "nav", "eventsink"), 1, NULL), e); } else if(event_is_action(e, ACTION_VOLUME_UP) || event_is_action(e, ACTION_VOLUME_DOWN)) { p = prop_get_by_name(PNVEC("global", "audio", "mastervolume"), 1, NULL); prop_add_float(p, event_is_action(e, ACTION_VOLUME_DOWN) ? -1 : 1); prop_ref_dec(p); } else if(event_is_action(e, ACTION_VOLUME_MUTE_TOGGLE)) { p = prop_get_by_name(PNVEC("global", "audio", "mastermute"), 1, NULL); prop_toggle_int(p); prop_ref_dec(p); } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD) || event_is_action(e, ACTION_SEEK_BACKWARD) || event_is_action(e, ACTION_SEEK_FAST_FORWARD) || event_is_action(e, ACTION_SEEK_FORWARD) || event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE) || event_is_action(e, ACTION_STOP) || event_is_action(e, ACTION_EJECT) || event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_SHOW_MEDIA_STATS) || event_is_action(e, ACTION_SHUFFLE) || event_is_action(e, ACTION_REPEAT) || event_is_action(e, ACTION_NEXT_CHANNEL) || event_is_action(e, ACTION_PREV_CHANNEL) || event_is_action(e, ACTION_CYCLE_AUDIO) || event_is_action(e, ACTION_CYCLE_SUBTITLE) || event_is_type(e, EVENT_SELECT_AUDIO_TRACK) || event_is_type(e, EVENT_SELECT_SUBTITLE_TRACK) ) { event_to_prop(prop_get_by_name(PNVEC("global", "media", "eventsink"), 1, NULL), e); } else if(event_is_type(e, EVENT_PLAYTRACK)) { event_to_prop(prop_get_by_name(PNVEC("global", "playqueue", "eventsink"), 1, NULL), e); } event_release(e); }
/** * Play given track. * * We only expect this to be called from the playqueue system. */ static event_t * be_sid2player_play(const char *url0, media_pipe_t *mp, char *errbuf, size_t errlen, int hold, const char *mimetype) { media_queue_t *mq = &mp->mp_audio; char *url, *p; int sample = 0; media_buf_t *mb = NULL; event_t *e; int subsong; int registered_play = 0; void *player; url0 += strlen("sidplayer:"); url = mystrdupa(url0); p = strrchr(url, '/'); if(p == NULL) { snprintf(errbuf, errlen, "Invalid filename"); return NULL; } *p++= 0; subsong = atoi(p); buf_t *b; if((b = fa_load(url, NULL, errbuf, errlen, NULL, 0, NULL, NULL)) == NULL) return NULL; player = sidcxx_load(b->b_ptr, b->b_size, subsong, errbuf, errlen); buf_release(b); if(player == NULL) return NULL; mp_set_playstatus_by_hold(mp, hold, NULL); mp->mp_audio.mq_stream = 0; mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_NONE, 0); mp_become_primary(mp); while(1) { if(mb == NULL) { mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_rate = 44100; mb->mb_pts = sample * 1000000LL / mb->mb_rate; mb->mb_drive_clock = 1; if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) { registered_play = 1; metadb_register_play(url0, 1, CONTENT_AUDIO); } sample += CHUNK_SIZE; int16_t *samples = mb->mb_data; sidcxx_play(player, samples, CHUNK_SIZE * sizeof(int16_t) * mb->mb_channels); // Crossmix 25% int i, l, r, L, R; for(i = 0; i < CHUNK_SIZE; i++) { l = samples[i * 2 + 0]; r = samples[i * 2 + 1]; L = 3 * l + r * 2; R = 3 * r + l * 2; L = L / 4; R = R / 4; if(L > 32767) L = 32767; if(L < -32768) L = -32768; if(R > 32767) R = 32767; if(R < -32768) R = -32768; samples[i * 2 + 0] = L; samples[i * 2 + 1] = R; } } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } sidcxx_stop(player); return e; }
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; }