static uint16_t _find_selected_button_id(GRAPHICS_CONTROLLER *gc) { /* executed when playback condition changes (ex. new page, popup-on, ...) */ PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned ii; page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_TRACE("_find_selected_button_id(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return 0xffff; } /* run 5.9.8.3 */ /* 1) always use page->default_selected_button_id_ref if it is valid */ if (_find_button_page(page, page->default_selected_button_id_ref, NULL) && _is_button_enabled(gc, page, page->default_selected_button_id_ref)) { GC_TRACE("_find_selected_button_id() -> default #%d\n", page->default_selected_button_id_ref); return page->default_selected_button_id_ref; } /* 2) fallback to current PSR10 value if it is valid */ for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; uint16_t enabled_button = gc->bog_data[ii].enabled_button; if (button_id == enabled_button) { if (_find_button_bog(bog, enabled_button)) { GC_TRACE("_find_selected_button_id() -> PSR10 #%d\n", enabled_button); return enabled_button; } } } /* 3) fallback to find first valid_button_id_ref from page */ for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; uint16_t enabled_button = gc->bog_data[ii].enabled_button; if (_find_button_bog(bog, enabled_button)) { GC_TRACE("_find_selected_button_id() -> first valid #%d\n", enabled_button); return enabled_button; } } GC_TRACE("_find_selected_button_id(): not found -> 0xffff\n"); return 0xffff; }
static int _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned cur_btn_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned new_btn_id = 0xffff; unsigned ii; gc->valid_mouse_position = 0; page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { ERROR("_mouse_move(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->enabled_button[ii]; BD_IG_BUTTON *button = _find_button_bog(bog, valid_id); if (!button) continue; if (x < button->x_pos || y < button->y_pos) continue; /* Check for SELECTED state object (button that can be selected) */ BD_PG_OBJECT *object = _find_object_for_button(s, button, BTN_SELECTED); if (!object) continue; if (x >= button->x_pos + object->width || y >= button->y_pos + object->height) continue; /* mouse is over button */ /* is button already selected? */ if (button->id == cur_btn_id) { gc->valid_mouse_position = 1; return 0; } new_btn_id = button->id; break; } if (new_btn_id != 0xffff) { bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, new_btn_id); _render_page(gc, -1, cmds); gc->valid_mouse_position = 1; } return gc->valid_mouse_position; }
static void _update_selected_button(GRAPHICS_CONTROLLER *gc) { unsigned button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); TRACE("_update_enabled_button(): currently enabled button is #%d\n", button_id); // special case: triggered only after enable button disables selected button if (button_id & 0x10000) { button_id &= 0xffff; bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, button_id); TRACE("_update_enabled_button() -> #%d [last enabled]\n", button_id); return; } if (button_id == 0xffff) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { TRACE("_update_enabled_button(): unknown page #%d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return; } // run 5.9.8.3 if (_find_button_page(page, page->default_selected_button_id_ref, NULL) && _is_button_enabled(gc, page, page->default_selected_button_id_ref)) { button_id = page->default_selected_button_id_ref; } else { unsigned ii; for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; if (_find_button_bog(bog, gc->enabled_button[ii])) { button_id = gc->enabled_button[ii]; break; } } } bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, button_id); TRACE("_update_enabled_button() -> #%d\n", button_id); } }
static BD_IG_BUTTON *_find_button_page(BD_IG_PAGE *page, unsigned button_id, unsigned *bog_idx) { unsigned ii; for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BUTTON *button = _find_button_bog(&page->bog[ii], button_id); if (button) { if (bog_idx) { *bog_idx = ii; } return button; } } return NULL; }
static int _user_input(GRAPHICS_CONTROLLER *gc, uint32_t key, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned cur_btn_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); unsigned new_btn_id = cur_btn_id; unsigned ii; int activated_btn_id = -1; if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { GC_TRACE("_user_input(): popup menu not visible\n"); return -1; } if (!gc->ig_drawn) { GC_ERROR("_user_input(): menu not visible\n"); return -1; } GC_TRACE("_user_input(%d)\n", key); page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_user_input(): unknown page id %d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } if (key == BD_VK_MOUSE_ACTIVATE) { if (!gc->valid_mouse_position) { GC_TRACE("_user_input(): BD_VK_MOUSE_ACTIVATE outside of valid buttons\n"); return -1; } key = BD_VK_ENTER; } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; BD_IG_BUTTON *button = _find_button_bog(bog, valid_id); if (!button) { continue; } /* numeric select */ if (VK_IS_NUMERIC(key)) { if (button->numeric_select_value == VK_TO_NUMBER(key)) { new_btn_id = button->id; } } /* cursor keys */ else if (VK_IS_CURSOR(key) || key == BD_VK_ENTER) { if (button->id == cur_btn_id) { switch(key) { case BD_VK_UP: new_btn_id = button->upper_button_id_ref; break; case BD_VK_DOWN: new_btn_id = button->lower_button_id_ref; break; case BD_VK_LEFT: new_btn_id = button->left_button_id_ref; break; case BD_VK_RIGHT: new_btn_id = button->right_button_id_ref; break; case BD_VK_ENTER: activated_btn_id = cur_btn_id; cmds->num_nav_cmds = button->num_nav_cmds; cmds->nav_cmds = button->nav_cmds; cmds->sound_id_ref = button->activated_sound_id_ref; break; default:; } } if (new_btn_id != cur_btn_id) { BD_IG_BUTTON *new_button = _find_button_page(page, new_btn_id, NULL); if (new_button) { cmds->sound_id_ref = new_button->selected_sound_id_ref; } } } } /* render page ? */ if (new_btn_id != cur_btn_id || activated_btn_id >= 0) { _select_button(gc, new_btn_id); _render_page(gc, activated_btn_id, cmds); /* found one*/ return 1; } return 0; }
static int _render_page(GRAPHICS_CONTROLLER *gc, unsigned activated_button_id, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; BD_PG_PALETTE *palette = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned ii; unsigned selected_button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { if (gc->ig_open) { GC_TRACE("_render_page(): popup menu not visible\n"); _close_osd(gc, BD_OVERLAY_IG); return 1; } return 0; } page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { GC_ERROR("_render_page: unknown page id %d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return -1; } palette = _find_palette(s, page->palette_id_ref); if (!palette) { GC_ERROR("_render_page: unknown palette id %d (have %d palettes)\n", page->palette_id_ref, s->num_palette); return -1; } GC_TRACE("rendering page #%d using palette #%d. page has %d bogs\n", page->id, page->palette_id_ref, page->num_bogs); if (!gc->ig_open) { _open_osd(gc, BD_OVERLAY_IG, s->ics->video_descriptor.video_width, s->ics->video_descriptor.video_height); } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->bog_data[ii].enabled_button; BD_IG_BUTTON *button; button = _find_button_bog(bog, valid_id); if (!button) { GC_TRACE("_render_page(): bog %d: button %d not found\n", ii, valid_id); // render background _clear_bog_area(gc, &gc->bog_data[ii]); } else if (button->id == activated_button_id) { GC_TRACE(" button #%d activated\n", button->id); _render_button(gc, button, palette, BTN_ACTIVATED, &gc->bog_data[ii]); } else if (button->id == selected_button_id) { if (button->auto_action_flag && !gc->auto_action_triggered) { if (cmds) { GC_TRACE(" auto-activate #%d\n", button->id); cmds->num_nav_cmds = button->num_nav_cmds; cmds->nav_cmds = button->nav_cmds; gc->auto_action_triggered = 1; } else { GC_ERROR(" auto-activate #%d not triggered (!cmds)\n", button->id); } _render_button(gc, button, palette, BTN_ACTIVATED, &gc->bog_data[ii]); } else { _render_button(gc, button, palette, BTN_SELECTED, &gc->bog_data[ii]); } } else { _render_button(gc, button, palette, BTN_NORMAL, &gc->bog_data[ii]); } } if (gc->ig_dirty) { _flush_osd(gc, BD_OVERLAY_IG, -1); gc->ig_dirty = 0; return 1; } return 0; }
static void _render_page(GRAPHICS_CONTROLLER *gc, unsigned activated_button_id, GC_NAV_CMDS *cmds) { PG_DISPLAY_SET *s = gc->igs; BD_IG_PAGE *page = NULL; BD_PG_PALETTE *palette = NULL; unsigned page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID); unsigned ii; unsigned selected_button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID); if (s->ics->interactive_composition.ui_model == IG_UI_MODEL_POPUP && !gc->popup_visible) { TRACE("_render_page(): popup menu not visible\n"); _gc_clear_osd(gc, 1); return; } page = _find_page(&s->ics->interactive_composition, page_id); if (!page) { ERROR("_render_page: unknown page id %d (have %d pages)\n", page_id, s->ics->interactive_composition.num_pages); return; } palette = _find_palette(s, page->palette_id_ref); if (!palette) { ERROR("_render_page: unknown palette id %d (have %d palettes)\n", page->palette_id_ref, s->num_palette); return; } TRACE("rendering page #%d using palette #%d. page has %d bogs\n", page->id, page->palette_id_ref, page->num_bogs); if (selected_button_id == 0xffff) { selected_button_id = page->default_selected_button_id_ref; } for (ii = 0; ii < page->num_bogs; ii++) { BD_IG_BOG *bog = &page->bog[ii]; unsigned valid_id = gc->enabled_button[ii]; BD_IG_BUTTON *button; button = _find_button_bog(bog, valid_id); if (!button) { TRACE("_render_page(): bog %d: button %d not found\n", ii, valid_id); } else if (button->id == activated_button_id) { _render_button(gc, button, palette, BTN_ACTIVATED); } else if (button->id == selected_button_id) { _render_button(gc, button, palette, BTN_SELECTED); bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, selected_button_id); if (button->auto_action_flag) { cmds->num_nav_cmds = button->num_nav_cmds; cmds->nav_cmds = button->nav_cmds; } } else { _render_button(gc, button, palette, BTN_NORMAL); } } }