void gf_term_mouse_input(GF_Terminal *term, GF_EventMouse *event) { s32 X, Y; u32 left_but_down, middle_but_down, right_but_down; SFFloat wheel_pos; u32 i; GF_Codec *cod; GF_BitStream *bs; GF_SLHeader slh; char *buf; u32 buf_size; Fixed bX, bY; if (!term || !gf_list_count(term->input_streams)) return; X = event->x; Y = event->y; left_but_down = middle_but_down = right_but_down = 0; wheel_pos = 0; switch (event->type) { case GF_EVENT_MOUSEDOWN: if (event->button==GF_MOUSE_RIGHT) right_but_down = 2; else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 2; else if (event->button==GF_MOUSE_LEFT) left_but_down = 2; break; case GF_EVENT_MOUSEUP: if (event->button==GF_MOUSE_RIGHT) right_but_down = 1; else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 1; else if (event->button==GF_MOUSE_LEFT) left_but_down = 1; break; case GF_EVENT_MOUSEWHEEL: wheel_pos = event->wheel_pos; break; case GF_EVENT_MOUSEMOVE: break; default: return; } /*get BIFS coordinates*/ gf_sr_map_point(term->renderer, X, Y, &bX, &bY); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*If wheel is specified disable X and Y (bug from MS wheel handling)*/ if (wheel_pos) { gf_bs_write_int(bs, 0, 1); } else { gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, FIX2FLT(bX)); gf_bs_write_float(bs, FIX2FLT(bY)); } gf_bs_write_int(bs, left_but_down ? 1 : 0, 1); if (left_but_down) gf_bs_write_int(bs, left_but_down-1, 1); gf_bs_write_int(bs, middle_but_down ? 1 : 0, 1); if (middle_but_down) gf_bs_write_int(bs, middle_but_down-1, 1); gf_bs_write_int(bs, right_but_down ? 1 : 0, 1); if (right_but_down) gf_bs_write_int(bs, right_but_down-1, 1); if (wheel_pos==0) { gf_bs_write_int(bs, 0, 1); } else { gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, FIX2FLT(wheel_pos) ); } gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStampFlag = 1; /*note we could use an exact TS but it's not needed: since the input is generated locally we want it to be decoded as soon as possible, thus using 0 emulates permanent seeking on InputSensor stream, hence forces input frame resync*/ slh.compositionTimeStamp = 0; /*get all IS Mouse decoders and send frame*/ i=0; while ((cod = (GF_Codec*)gf_list_enum(term->input_streams, &i))) { ISPriv *is = (ISPriv *)cod->decio->privateStack; if (is->type==IS_Mouse) { GF_Channel *ch = (GF_Channel *)gf_list_get(cod->inChannels, 0); gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); } } free(buf); }
GF_DBUnit *gf_es_get_au(GF_Channel *ch) { Bool comp, is_new_data; GF_Err e, state; GF_SLHeader slh; if (ch->es_state != GF_ESM_ES_RUNNING) return NULL; if (!ch->is_pulling) { /*we must update buffering before fetching in order to stop buffering for streams with very few updates (especially streams with one update, like most of OD streams)*/ if (ch->BufferOn) Channel_UpdateBuffering(ch, 0); if (ch->first_au_fetched && ch->BufferOn) return NULL; return ch->AU_buffer_first; } /*pull from stream - resume clock if needed*/ ch_buffer_off(ch); memset(&slh, 0, sizeof(GF_SLHeader)); e = gf_term_channel_get_sl_packet(ch->service, ch, (char **) &ch->AU_buffer_pull->data, &ch->AU_buffer_pull->dataLength, &slh, &comp, &state, &is_new_data); if (e) state = e; switch (state) { case GF_EOS: gf_es_on_eos(ch); return NULL; case GF_OK: break; default: { char m[100]; sprintf(m, "Data reception failure on channel %d", ch->esd->ESID); gf_term_message(ch->odm->term, ch->service->url , m, state); return NULL; } } assert(!comp); /*update timing if new stream data but send no data*/ if (is_new_data) { gf_es_receive_sl_packet(ch->service, ch, NULL, 0, &slh, GF_OK); if (ch->ipmp_tool) { GF_IPMPEvent evt; memset(&evt, 0, sizeof(evt)); evt.event_type=GF_IPMP_TOOL_PROCESS_DATA; evt.data = ch->AU_buffer_pull->data; evt.data_size = ch->AU_buffer_pull->dataLength; evt.is_encrypted = slh.isma_encrypted; evt.isma_BSO = slh.isma_BSO; evt.channel = ch; e = ch->ipmp_tool->process(ch->ipmp_tool, &evt); /*we discard undecrypted AU*/ if (e) { if (e==GF_EOS) { gf_es_on_eos(ch); /*restart*/ if (evt.restart_requested) { if (ch->odm->parentscene->is_dynamic_scene) { gf_scene_restart_dynamic(ch->odm->parentscene, 0); } else { mediacontrol_restart(ch->odm); } } } gf_term_channel_release_sl_packet(ch->service, ch); return NULL; } } } /*this may happen in file streaming when data has not arrived yet, in which case we discard the AU*/ if (!ch->AU_buffer_pull->data) { gf_term_channel_release_sl_packet(ch->service, ch); return NULL; } ch->AU_buffer_pull->CTS = (u32) ch->CTS; ch->AU_buffer_pull->DTS = (u32) ch->DTS; ch->AU_buffer_pull->PaddingBits = ch->padingBits; if (ch->IsRap) ch->AU_buffer_pull->flags |= GF_DB_AU_RAP; return ch->AU_buffer_pull; }