📄 xineplug_inp_vcd.c
字号:
switch (vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: switch (vcdplayer->slider_length) { case VCDPLAYER_SLIDER_LENGTH_AUTO: case VCDPLAYER_SLIDER_LENGTH_ENTRY: n += ip->class->mrl_entry_offset; break; case VCDPLAYER_SLIDER_LENGTH_TRACK: n = vcdinfo_get_track(vcdplayer->vcd, n) + ip->class->mrl_track_offset; break; default: /* FIXME? */ return -1; } break; case VCDINFO_ITEM_TYPE_TRACK: n += ip->class->mrl_track_offset; break; case VCDINFO_ITEM_TYPE_SEGMENT: n += ip->class->mrl_segment_offset; break; case VCDINFO_ITEM_TYPE_LID: /* This is the only situation where the size of the current play item is not static. It depends what the current play-item is. */ old_get_length = (vcdplayer->end_lsn - vcdplayer->origin_lsn) * M2F2_SECTOR_SIZE; return old_get_length; break; case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_SPAREID2: default: /* FIXME? */ return -1; } if (n >= 0 && n < ip->class->num_mrls) { old_get_length = ip->class->mrls[n]->size; dbg_print(INPUT_DBG_MRL, "item: %u, slot %u, size %ld\n", vcdplayer->play_item.num, (unsigned int) n, (long int) old_get_length); } return old_get_length;}/*! * From xine plugin spec: * get current position in stream. * */static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen){ // trace_print("Called\n"); return (vcd_plugin_seek (this_gen, 0, SEEK_CUR));}/*! * From xine plugin spec: * return block size of input source (if supported, 0 otherwise) */static uint32_t vcd_plugin_get_blocksize (input_plugin_t *this_gen) { dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); return M2F2_SECTOR_SIZE;}/*! From xine plugin spec: ls function return value: NULL => filename is a file, **char=> filename is a dir-- This list returned forms the entries of the GUI MRL "browser".*/static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *filename, int *num_files) { char intended_vcd_device[MAX_DEVICE_LEN+1]= { '\0', }; vcdinfo_itemid_t itemid; vcd_input_class_t *class = (vcd_input_class_t *) this_gen; vcdplayer_t *vcdplayer= &my_vcd.player; bool used_default; if (filename == NULL) { dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called with NULL\n"); if ( class->mrls != NULL && NULL != class->mrls[0] ) goto have_mrls; if ( !vcd_build_mrl_list(class, vcdplayer->psz_source) ) { goto no_mrls; } } else { char *mrl = strdup(filename); dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called with %s\n", filename); if (!vcd_get_default_device(class, true)) goto no_mrls; if (!vcd_parse_mrl(class->vcd_device, mrl, intended_vcd_device, &itemid, vcdplayer->default_autoplay, &used_default)) { free (mrl); goto no_mrls; } free (mrl); } have_mrls: *num_files = class->num_mrls; return class->mrls; no_mrls: *num_files = 0; return NULL; }#define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL;static voidvcd_close(vcd_input_class_t *class) { xine_free_mrls(&(class->num_mrls), class->mrls); FREE_AND_NULL(my_vcd.mrl); if (my_vcd.player.b_opened) vcdio_close(&my_vcd.player);}/*! * From plugin xine spec: * eject/load the media (if it's possible) * * returns 0 for temporary failures */static int vcd_class_eject_media (input_class_t *this_gen) { int ret; CdIo_t *cdio=vcdinfo_get_cd_image(my_vcd.player.vcd); dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); if (NULL == cdio) return 0; ret = cdio_eject_media(&cdio); if ((ret == 0) || (ret == 2)) { if (my_vcd.player.b_opened) vcdio_close(&my_vcd.player); return 1; } else return 0;}/*! * From spec: * return current MRL */static char * vcd_plugin_get_mrl (input_plugin_t *this_gen) { vcd_input_plugin_t *t = (vcd_input_plugin_t *) this_gen; vcdplayer_t *vcdplayer = &my_vcd.player; int n; int size; /* need something to feed get_mrl_type_offset */ int offset; if (vcdplayer_pbc_is_on(vcdplayer)) { n = vcdplayer->i_lid; offset = vcd_get_mrl_type_offset(t, VCDINFO_ITEM_TYPE_LID, &size); } else { n = vcdplayer->play_item.num; offset = vcd_get_mrl_type_offset(t, vcdplayer->play_item.type, &size); } if (-2 == offset) { /* Bad type. */ LOG_ERR("%s %d", _("Invalid current entry type"), vcdplayer->play_item.type); return strdup(""); } else { n += offset; if (n < t->class->num_mrls) { dbg_print(INPUT_DBG_CALL, "Called, returning %s\n", t->class->mrls[n]->mrl); return t->class->mrls[n]->mrl; } else { return strdup(""); } }}/*! From xine plugin spec: return human readable (verbose = 1 line) description for this plugin*/static char *vcd_class_get_description (input_class_t *this_gen) { dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); return _("Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... ");}/*! From xine plugin spec: return short, human readable identifier for this plugin this is used for GUI buttons, The identifier must have max. 4 characters characters (max. 5 including terminating \0)*/static const char *vcd_class_get_identifier (input_class_t *this_gen) { dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); return SHORT_PLUGIN_NAME;}/* Handle all queued keyboard/mouse events. Return TRUE if this causes a change in the play item.*/static boolvcd_handle_events (void) { vcdplayer_t *p_vcdplayer = &my_vcd.player; xine_event_t *p_event; int digit_entered=0; /* What you add to the last input number entry. It accumulates all of the 10_ADD keypresses */ static unsigned int number_addend = 0; while ((p_event = xine_event_get(my_vcd.event_queue))) { dbg_print( (INPUT_DBG_CALL), "processing %d\n", p_event->type ); digit_entered=0; switch(p_event->type) { case XINE_EVENT_INPUT_NUMBER_10_ADD: number_addend += 10; dbg_print(INPUT_DBG_EVENT, "10 added to number. Is now: %d\n", number_addend); break; /* The method used below is oblivious to XINE_EVENT_INPUT encodings In particular, it does not assume XINE_EVENT_INPUT_NUMBE_9 = XINE_EVENT_INPUT_NUMBER_0 + 9. */ case XINE_EVENT_INPUT_NUMBER_9: digit_entered++; case XINE_EVENT_INPUT_NUMBER_8: digit_entered++; case XINE_EVENT_INPUT_NUMBER_7: digit_entered++; case XINE_EVENT_INPUT_NUMBER_6: digit_entered++; case XINE_EVENT_INPUT_NUMBER_5: digit_entered++; case XINE_EVENT_INPUT_NUMBER_4: digit_entered++; case XINE_EVENT_INPUT_NUMBER_3: digit_entered++; case XINE_EVENT_INPUT_NUMBER_2: digit_entered++; case XINE_EVENT_INPUT_NUMBER_1: digit_entered++; case XINE_EVENT_INPUT_NUMBER_0: { number_addend *= 10; number_addend += digit_entered; dbg_print(INPUT_DBG_EVENT, "digit added number is now: %d\n", number_addend); break; } case XINE_EVENT_INPUT_MENU3: dbg_print(INPUT_DBG_EVENT, "menu3 setting debug: %d\n", number_addend); vcdplayer_debug = number_addend; number_addend = 0; break; case XINE_EVENT_INPUT_MENU1: case XINE_EVENT_INPUT_MENU2: case XINE_EVENT_INPUT_NEXT: case XINE_EVENT_INPUT_PREVIOUS: { int num = number_addend; vcdinfo_itemid_t itemid; number_addend = 0; /* If no number was given it's really the same as 1, not 0. */ if (num == 0) num++; dbg_print(INPUT_DBG_EVENT, "RETURN/NEXT/PREV/DEFAULT (%d) iteration count %d\n", p_event->type, num); for ( ; num > 0; num--) { itemid = p_vcdplayer->play_item; switch (p_event->type) { case XINE_EVENT_INPUT_MENU1: if (p_vcdplayer->return_entry == VCDINFO_INVALID_ENTRY) { LOG_MSG("%s\n", _("selection has no RETURN entry")); return false; } itemid.num = p_vcdplayer->return_entry; dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT), "RETURN to %d\n", itemid.num); /* Don't loop around -- doesn't make sense to loop a return*/ num = 0; break; case XINE_EVENT_INPUT_MENU2: if (vcdplayer_pbc_is_on(p_vcdplayer)) { lid_t lid=vcdinfo_get_multi_default_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, p_vcdplayer->i_lsn); if (VCDINFO_INVALID_LID != lid) { itemid.num = lid; dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT), "DEFAULT to %d\n", itemid.num); } else { dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT), "no DEFAULT for LID %d\n", p_vcdplayer->i_lid); } /* Don't loop around -- doesn't make sense to loop a return*/ num = 0; } else { /* PBC is not on. "default" selection beginning of current selection . Alternative: */ LOG_MSG("%s\n", _("DEFAULT selected, but PBC is not on.")); } break; case XINE_EVENT_INPUT_NEXT: if (p_vcdplayer->next_entry == VCDINFO_INVALID_ENTRY) { LOG_MSG("%s\n", _("selection has no NEXT entry")); return false; } itemid.num = p_vcdplayer->next_entry; dbg_print(INPUT_DBG_PBC, "NEXT to %d\n", itemid.num); break; case XINE_EVENT_INPUT_PREVIOUS: if (p_vcdplayer->prev_entry == VCDINFO_INVALID_ENTRY) { LOG_MSG("%s\n", _("selection has no PREVIOUS entry")); return false; } itemid.num = p_vcdplayer->prev_entry; dbg_print(INPUT_DBG_PBC, "PREVIOUS to %d\n", itemid.num); break; default: LOG_MSG("%s %d\n", _("Unknown event type: "), p_event->type); } _x_demux_flush_engine(my_vcd.stream); vcdplayer_play(p_vcdplayer, itemid); return true; } break; } case XINE_EVENT_INPUT_SELECT: { /* In the future will have to test to see if we are in a menu selection. But if not... */ vcdinfo_itemid_t itemid = p_vcdplayer->play_item; itemid.num = number_addend; number_addend = 0; if (vcdplayer_pbc_is_on(p_vcdplayer)) { lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, itemid.num); if (VCDINFO_INVALID_LID != i_next) { itemid.num = i_next; _x_demux_flush_engine(my_vcd.stream); vcdplayer_play(p_vcdplayer, itemid); return true; } } break; } case XINE_EVENT_INPUT_MOUSE_BUTTON: if (my_vcd.stream) { xine_input_data_t *p_input = p_event->data; if (p_input->button == 1) {#if LIBVCD_VERSION_NUM >= 23 int i_selection;#endif dbg_print(INPUT_DBG_EVENT, "Button to x: %d, y: %d, scaled x: %d, scaled y %d\n", p_input->x, p_input->y, p_input->x * 255 / p_vcdplayer->max_x, p_input->y * 255 / p_vcdplayer->max_y); #if LIBVCD_VERSION_NUM >= 23 /* xine_dvd_send_button_update(this, 1); */ if (my_vcd.b_mouse_in) send_mouse_enter_leave_event(&my_vcd, false); i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd, p_vcdplayer->i_lid,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -