static int dd_read(de_dev_t *dd) { struct input_event ie; event_t *e = NULL; int i; if(read(dd->dd_fd, &ie, 16) != 16) return 1; if(ie.type == EV_REL) { if(ie.code == REL_WHEEL) { int action = ie.value < 0 ? ACTION_DOWN : ACTION_UP; int cnt = abs(ie.value); if(cnt > 4) cnt = 4; while(cnt--) { e = event_create_action(action); event_to_ui(e); } } return 0; } if(ie.type != EV_KEY) return 0; doqual(dd, &ie, KEY_LEFTSHIFT, QUAL_LEFT_SHIFT); doqual(dd, &ie, KEY_RIGHTSHIFT, QUAL_RIGHT_SHIFT); if(ie.value == 0) return 0; // release int shift = !!(dd->dd_qual & (QUAL_LEFT_SHIFT | QUAL_RIGHT_SHIFT)); for(i = 0; key_to_action[i][0]; i++) { if(key_to_action[i][0] == ie.code) { event_to_ui(event_create_action(key_to_action[i][1+shift])); return 0; } } switch(ie.code) { case KEY_SPACE: e = event_create_int(EVENT_UNICODE, 32); break; case KEY_ENTER: e = event_create_action_multi((const action_type_t[]){ ACTION_ACTIVATE, ACTION_ENTER}, 2); break; case KEY_BACKSPACE: e = event_create_action_multi((const action_type_t[]){ ACTION_BS, ACTION_NAV_BACK}, 2);
static void eventsink(void *opaque, prop_event_t event, ...) { event_t *e, **ep = opaque; va_list ap; va_start(ap, event); switch(event) { default: break; case PROP_EXT_EVENT: if(*ep) event_release(*ep); e = va_arg(ap, event_t *); atomic_inc(&e->e_refcount); *ep = e; break; case PROP_DESTROYED: if(*ep) event_release(*ep); *ep = event_create_action(ACTION_CANCEL); break; } }
static htsmsg_t * avt_Stop(http_connection_t *hc, htsmsg_t *args, const char *myhost, int myport) { event_dispatch(event_create_action(ACTION_STOP)); return NULL; }
static void * do_shutdown(void *aux) { shutdown_hook_run(2); event_dispatch(event_create_action(ACTION_STOP)); prop_destroy_by_name(prop_get_global(), "popups"); app_flush_caches(); TRACE(TRACE_DEBUG, "core", "Caches flushed"); int r = arch_stop_req(); TRACE(TRACE_DEBUG, "core", "arch stop=%d", r); if(!r) { // If arch_stop_req() returns -1 it will not actually // exit showtime but rather suspend the UI and turn off HDMI ,etc // Typically used on some targets where we want to enter a // semi-standby state. // So only do shutdown hooks if we are about to exit for real. // Run early shutdown hooks (those must be fast since this // function may be called from UI thread) shutdown_hook_run(1); } return NULL; }
static htsmsg_t * avt_Previous(http_connection_t *hc, htsmsg_t *args, const char *myhost, int myport) { event_dispatch(event_create_action(ACTION_SKIP_BACKWARD)); return NULL; }
void mp_become_primary(struct media_pipe *mp) { mp_init_audio(mp); if(media_primary == mp) return; hts_mutex_lock(&media_mutex); assert(mp->mp_flags & MP_PRIMABLE); if(media_primary != NULL) { prop_set_int(media_primary->mp_prop_primary, 0); event_t *e = event_create_action(ACTION_STOP); mp_enqueue_event(media_primary, e); event_release(e); } media_primary = mp_retain(mp); prop_select(mp->mp_prop_root); prop_link(mp->mp_prop_root, media_prop_current); prop_set_int(mp->mp_prop_primary, 1); hts_mutex_unlock(&media_mutex); }
event_t * event_create_action_str(const char *str) { action_type_t a = action_str2code(str); if(a == -1) return event_create_str(EVENT_DYNAMIC_ACTION, str); return event_create_action(a); }
event_t * event_from_Fkey(unsigned int keynum, unsigned int mod) { if(keynum < 1 || keynum > 12 || mod > 1) return NULL; int a = action_from_fkey[keynum][mod]; if(a == 0) return NULL; return event_create_action(a); }
static int keypress(void *aux, const cec_keypress kp) { event_t *e = NULL; if(gconf.enable_cec_debug) TRACE(TRACE_DEBUG, "CEC", "Got keypress code=0x%x duration=0x%x", kp.keycode, kp.duration); if(longpress_select) { if(kp.keycode == CEC_USER_CONTROL_CODE_SELECT) { if(kp.duration == 0) return 0; if(kp.duration < 500) e = event_create_action(ACTION_ACTIVATE); else e = event_create_action(ACTION_ITEMMENU); } } if(e == NULL) { const action_type_t *avec = NULL; if(kp.duration == 0 || kp.keycode == cec_config.comboKey) { avec = btn_to_action[kp.keycode]; } if(avec != NULL) { int i = 0; while(avec[i] != 0) i++; e = event_create_action_multi(avec, i); } } if(e != NULL) { e->e_flags |= EVENT_KEYPRESS; event_to_ui(e); } return 1; }
static void popup_send_result(popup_t *pop, action_type_t res) { prop_t *p; p = prop_get_by_name(PNVEC("self", "eventSink"), 1, PROP_TAG_NAMED_ROOT, pop->p, "self", NULL); if(p != NULL) { event_t *e = event_create_action(res); prop_send_ext_event(p, e); event_release(e); prop_ref_dec(p); } }
static void osk_destroyed(glw_ps3_t *gp) { glw_t *w = gp->osk_widget; assert(w != NULL); if(!(w->glw_flags & GLW_DESTROYING)) { event_t *e = event_create_action(ACTION_SUBMIT); glw_event_to_widget(w, e); event_release(e); } glw_unref(w); gp->osk_widget = NULL; if(gp->osk_container != 0xFFFFFFFFU) lv2MemContinerDestroy(gp->osk_container); }
static gboolean window_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { gu_window_t *gw = user_data; if(event->keyval == GDK_F12) event_dispatch(event_create_action(ACTION_SWITCH_UI)); if(event->keyval == GDK_F11) { if(gw->gw_fullwindow) { if(gw->gw_fullscreen) { gtk_window_unfullscreen(GTK_WINDOW(gw->gw_window)); } else { gtk_window_fullscreen(GTK_WINDOW(gw->gw_window)); } } } return FALSE; }
static void btn(glw_ps3_t *gp, krepeat_t *kr, int pressed, action_type_t ac) { event_t *e; if(ac == ACTION_NONE) return; if(pressed) { if(kr->held_frames == 0 || (kr->held_frames > 30 && (kr->held_frames % 3 == 0))) { e = event_create_action(ac); glw_dispatch_event(&gp->gr.gr_uii, e); event_release(e); } kr->held_frames++; } else { kr->held_frames = 0; } }
static void * stdin_thread(void *aux) { unsigned char c, buffer[64]; int bufferptr = 0, r, escaped = 0; while(1) { event_t *e = NULL; if(escaped) { struct pollfd fds; fds.fd = 0; fds.events = POLLIN; if(poll(&fds, 1, 100) == 1) r = read(0, &c, 1); else r = 0; } else { r = read(0, &c, 1); } if(r == 1) { if(bufferptr == sizeof(buffer) - 1) bufferptr = 0; buffer[bufferptr++] = c; } escaped = 0; switch(buffer[0]) { case 8: case 0x7f: e = event_create_action_multi((const action_type_t[]){ ACTION_BS, ACTION_NAV_BACK}, 2); bufferptr = 0; break; case 10: e = event_create_action_multi((const action_type_t[]){ ACTION_ACTIVATE, ACTION_ENTER}, 2); bufferptr = 0; break; case 9: e = event_create_action(ACTION_FOCUS_NEXT); bufferptr = 0; break; case 32 ... 0x7e: bufferptr = 0; e = event_create_int(EVENT_UNICODE, buffer[0]); break; default: bufferptr = 0; break; case 0x1b: if(r == 0) { if(bufferptr == 1) e = event_create_action(ACTION_CANCEL); bufferptr = 0; } else { int i; escaped = 1; buffer[bufferptr] = 0; for(i = 0; i < sizeof(map) / sizeof(map[0]); i++) { if(!strcmp((const char *)map[i].codes, (const char *)buffer)) { if(map[i].action) { e = event_create_action(map[i].action); } else if(map[i].fkey) { e = event_from_Fkey(map[i].fkey, 0); } break; } } if(e == NULL) { #if 0 printf("Unmapped esc sequence: "); for(i = 0; i < bufferptr; i++) printf("0x%02x,", buffer[i]); printf("0x00\n"); #endif } } break; }
static void playpause_clicked(GtkToolButton *toolbutton, gpointer user_data) { playdeck_t *pd = user_data; event_dispatch(event_create_action(pd->pp_action)); }
static void next_clicked(GtkToolButton *toolbutton, gpointer user_data) { event_dispatch(event_create_action(ACTION_SKIP_FORWARD)); }
static void home_clicked(GtkToolButton *toolbutton, gpointer user_data) { gu_tab_t *gt = user_data; gu_tab_send_event(gt, event_create_action(ACTION_HOME)); }
static void next_clicked(GtkToolButton *toolbutton, gpointer user_data) { event_dispatch(event_create_action(ACTION_NEXT_TRACK)); }
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); }