/*************************************************************************** * Copyright (c) 2013, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * Liqun 01/29/2013, Add UI to display more EPG data per customer's request * * $brcm_Log: $ * ***************************************************************************/ #define MAX_GUIDE_ENTRIES 9 #ifdef CONFIG_DVB #include "dvb_parser.h" #endif /* Define to test guide drawing and selection control without PSIP guide data */ /* #define STATIC_GUIDE_TEST */ #define GUIDE_MIN(x,y) ((x < y) ? x : y) #define eSCREEN_GUIDE_X 82 #define eSCREEN_GUIDE_Y_OFF 130 #define eSCREEN_GUIDE_HEIGHT 30 #define eSCREEN_GUIDE_CH_WIDTH 55 #define eSCREEN_GUIDE_CALLSIGN_WIDTH 90 #define eSCREEN_GUIDE_CH_NAME_X 138 #define eSCREEN_GUIDE_CH_NAME_WIDTH 30 #define eSCREEN_GUIDE_NEXT_X 445 #define eSCREEN_GUIDE_CUR_X 235 #define eSCREEN_GUIDE_NAME_WIDTH 196 #define eSCREEN_GUIDE_SPACING 30 #define eSCREEN_DETAILED_GUIDE_X 255 #define eSCREEN_DETAILED_GUIDE_WIDTH 420 #define guide_text_box(s,f,x,y,w,h,m,l,cf,cb,o,lsp) text_box(s,f,x,y,w,h,m,l,cf,lsp) static void draw_guide_entry(bapp_t *p_app, bscreen_t *p_screen, guide_state_t *p_gs, int idx, chm_info_t *p_info, bool selected); static chm_info_t* screen_guide_get_info(bapp_t *p_app, int idx); static void draw_detailed_guide_entry(bapp_t *p_app, bscreen_t *p_screen, detailed_guide_state_t *p_gs,int idx, chm_info_t *p_info, bool selected); static void bscreen_detailed_guide_options_draw(void *v_app, void *v_screen); guide_state_t g_guide_state = { 0, 0, 1, "", { eS_EVENT_MAX, 0, 0}, 0, 0, 0 }; detailed_guide_state_t g_detailed_guide_state = { 0, 0, }; /* Summary: Guide event handling. return 0 if no redrawing should be done. */ int screen_guide_move(bapp_t *p_app, bscreen_t *p_screen, int up) { int start_idx,end_idx,num_disp,result,old_sel; guide_state_t *p_gs; p_gs = (guide_state_t*)p_screen->local_state; chm_info_t *p_info; chm_info_t *p_old_info; BDBG_ASSERT(p_gs); result = 0; if (p_app->settings.num_channels < 2) return result; start_idx = p_gs->offset; end_idx = GUIDE_MIN((p_app->settings.num_channels - 1), (p_gs->offset + (MAX_GUIDE_ENTRIES - 1))); num_disp = (end_idx - start_idx + 1); old_sel = p_gs->selection; /* If moving selection up */ if (up > 0) { if (p_gs->selection == 0) { /* already at top */ p_app->chm.epg_update_ch_num = 0; } else if (up >= MAX_GUIDE_ENTRIES) { /* jump one page up */ start_idx -= MAX_GUIDE_ENTRIES; p_gs->selection -= MAX_GUIDE_ENTRIES; if (start_idx < 0) { BDBG_ERR(("start_idx = %d < 0\n", start_idx)); start_idx = 0; p_gs->selection = start_idx; } p_gs->offset = start_idx; /* update from top of guild entry of current page */ p_app->chm.cur_ch_num = start_idx; p_app->chm.epg_update_ch_num = start_idx; if (p_app->chm.epg_update_ch_num > 0) p_app->chm.epg_update_ch_num--; result = 1; } else if (p_gs->selection > start_idx) { p_gs->selection--; p_old_info = screen_guide_get_info(p_app,old_sel); p_info = screen_guide_get_info(p_app,p_gs->selection); //bapp_sync(p_app); if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true); if (p_old_info) draw_guide_entry(p_app,p_screen,p_gs, old_sel,p_old_info,false); bapp_flush_screen(p_app); } else if (start_idx > 0) { start_idx -= MAX_GUIDE_ENTRIES; if (start_idx < 0) { BDBG_ERR(("start_idx = %d < 0\n", start_idx)); start_idx = 0; p_gs->selection = start_idx; } p_gs->offset = start_idx; p_gs->selection--; /* update from top of guild entry of current page */ p_app->chm.cur_ch_num = start_idx; p_app->chm.epg_update_ch_num = start_idx; if (p_app->chm.epg_update_ch_num > 0) p_app->chm.epg_update_ch_num--; result = 1; } else { /* Do nothing */ } } else /* moving selection down */ { if (p_gs->selection == (p_app->settings.num_channels - 1)) { /* already at bottom */ } else if (up <= -MAX_GUIDE_ENTRIES) { /* jump one page down */ p_gs->offset += MAX_GUIDE_ENTRIES; p_gs->selection += MAX_GUIDE_ENTRIES; if (p_gs->offset >= p_app->settings.num_channels) { BDBG_ERR(("p_gs->offset = %d >= %d\n", p_gs->offset,p_app->settings.num_channels)); p_gs->offset -= MAX_GUIDE_ENTRIES; } if (p_gs->selection >= p_app->settings.num_channels) { BDBG_ERR(("p_gs->selection = %d >= %d\n", p_gs->selection,p_app->settings.num_channels)); p_gs->selection = p_app->settings.num_channels - 1; } /* update from top of guild entry of current page */ p_app->chm.cur_ch_num = p_gs->offset; p_app->chm.epg_update_ch_num = p_gs->offset; if (p_app->chm.epg_update_ch_num > 0) p_app->chm.epg_update_ch_num--; result = 1; } else if (p_gs->selection < end_idx) { p_gs->selection++; p_old_info = screen_guide_get_info(p_app,old_sel); p_info = screen_guide_get_info(p_app,p_gs->selection); //bapp_sync(p_app); if (p_old_info) draw_guide_entry(p_app,p_screen,p_gs, old_sel,p_old_info,false); if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true); bapp_flush_screen(p_app); result = 1; } else if ((end_idx >= p_app->settings.num_channels) || (num_disp < MAX_GUIDE_ENTRIES)) { /* do nothing */ p_app->chm.epg_update_ch_num = p_app->chm.cur_ch_num; } else { p_gs->offset += MAX_GUIDE_ENTRIES; p_gs->selection++; if (p_gs->offset >= p_app->settings.num_channels) { BDBG_ERR(("p_gs->offset = %d >= %d\n", p_gs->offset,p_app->settings.num_channels)); p_gs->offset -= MAX_GUIDE_ENTRIES; p_gs->selection = p_app->settings.num_channels - 1; } /* update from top of guild entry of current page */ p_app->chm.cur_ch_num = p_gs->offset; p_app->chm.epg_update_ch_num = p_gs->offset; if (p_app->chm.epg_update_ch_num > 0) p_app->chm.epg_update_ch_num--; result = 1; } } return result; } /* * Summary: * Guide event handling. return 0 if no redrawing should be done. */ static void screen_guide_handle_redraw(bapp_t *p_app, bscreen_t *p_screen,guide_state_t *p_gs, int idx) { chm_info_t *p_info; int start_idx,end_idx; start_idx = p_gs->offset; end_idx = GUIDE_MIN((p_app->settings.num_channels - 1), (p_gs->offset + (MAX_GUIDE_ENTRIES - 1))); if ((idx < start_idx) || (idx > end_idx)) { return; } p_info = screen_guide_get_info(p_app,idx); /*bapp_sync(p_app);*/ if (p_info) draw_guide_entry(p_app,p_screen,p_gs, idx,p_info,(idx == p_gs->selection) ? true : false); bapp_flush_screen(p_app); } /* Summary: Guide event handling return result; . */ int screen_guide_event(void *v_app, void *v_screen, bscreen_event_t *p_event) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; guide_state_t *p_gs; int result = 0; p_gs = (guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); switch (p_event->type) { case eS_EVENT_SETUP: { bscreen_default_setup(v_app,v_screen); p_gs->column = 1; if (p_app->chm.cur_epg_ch_num) { p_gs->offset = (p_app->chm.cur_epg_ch_num /MAX_GUIDE_ENTRIES) * MAX_GUIDE_ENTRIES; p_gs->selection = p_app->chm.cur_epg_ch_num; /* we want to update from beginning in a page */ p_app->chm.epg_update_ch_num = p_gs->offset; } else { p_gs->selection = 0; p_gs->offset = 0; p_app->chm.epg_update_ch_num = 0; } memset(&p_gs->event,0,sizeof(p_gs->event)); p_gs->repeat_rate = 1; p_gs->repeat_timeout = DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate; result = 1; /* always handle event */ /* if enter the guide screen, retune is needed when quiting from the UI */ p_app->re_tune = true; } break; case eS_EVENT_SETUP_DONE: { if (p_app->settings.num_channels == 0) { /* set update progress to done since there are no channels */ p_gs->update_progress = 100; } else { p_gs->update_progress = 0; } p_app->chm.last_freq_hz = 0; p_app->chm_cmd.cmd_id = eCHM_GUIDE; chm_cmd(&p_app->chm, &p_app->chm_cmd); bos_sleep(100); /* give time for command to be processed */ } break; case eS_EVENT_PROGRESS: { p_gs->update_progress = p_event->id; if (p_gs->update_progress <= 100) { int num_chars = SCREEN_MAX_STR_WIDTH; int w = 0; int h = 0; /* draw progress text */ bscreen_get_string(p_app->lang,eTEXT_GUIDE_DL_PROGRESS, p_app->tmp_str, &num_chars); bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], ePROGRESS_GUIDE_X - w - 7, ePROGRESS_GUIDE_TEXT_Y - 4, w + 3, ePROGRESS_GUIDE_TEXT_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,100); bscreen_draw_progress(v_app, ePROGRESS_GUIDE_X, ePROGRESS_GUIDE_Y, ePROGRESS_GUIDE_WIDTH, ePROGRESS_GUIDE_HEIGHT, eBUTTON_VOL_PROGRESS_BORDER, eCOLOR_WHITE, eCOLOR_DRK_BLUE, p_gs->update_progress, 100); /* update entry if with current display screen since redrew message was overwroten by progress message */ { /* adjust channel index to previous one */ int idx = p_app->chm.cur_ch_num - 1; if (idx < 0) { if (p_app->settings.num_channels > 1) idx = (p_app->settings.num_channels - 1); else idx = 0; } screen_guide_handle_redraw(p_app,p_screen,p_gs, idx); } } else { //bgfx_fill_rect(&p_app->surf,ePROGRESS_GUIDE_TEXT_X,ePROGRESS_GUIDE_Y, // ePROGRESS_GUIDE_X+ePROGRESS_GUIDE_WIDTH-ePROGRESS_GUIDE_TEXT_X+3,ePROGRESS_GUIDE_HEIGHT+3,eCOLOR_LT_BLUE); } bapp_flush_screen(p_app); } break; case eS_EVENT_REDRAW: { screen_guide_handle_redraw(p_app,p_screen,p_gs,p_event->id); /*bapp_new_screen(p_app);*/ } break; case eS_EVENT_IR: { switch (p_event->id) { case eIR_SELECT: if (p_gs->column == 1) { if (p_app->settings.ch[p_gs->selection].skip) { /* skip channel, don't allow to quit? */ result = 1; break; } p_app->cur_ch_num = p_gs->selection; bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]); bapp_set_current_screen(p_app,eSCREEN_BANNER_SMALL,eSCREEN_NULL); #ifdef CONFIG_CH_HIDDEN if (!p_app->settings.wiz_completed) { p_app->settings.wiz_completed = true; /* select exits to live tv so we must clear all the button selection history for all screens */ bapp_clear_screen_selection_history(p_app); } #endif bapp_enable_cc(p_app, true); if (p_app->system_mute) bapp_audio_do_mute(p_app, false); bapp_audio_mute(p_app, false); } else { #ifdef CONFIG_CH_HIDDEN /* add/remove channel from ch+/- list */ if (p_gs->selection < p_app->settings.num_channels) p_app->settings.ch[p_gs->selection].hidden = !p_app->settings.ch[p_gs->selection].hidden; p_app->settings_dirty = 1; p_info = screen_guide_get_info(p_app,p_gs->selection); //bapp_sync(p_app); if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true); bapp_flush_screen(p_app); #endif } result = 1; break; #ifdef CONFIG_CH_HIDDEN case eIR_LEFT: { if (p_gs->column != 0) { p_info = screen_guide_get_info(p_app,p_gs->selection); //bapp_sync(p_app); if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,false); p_gs->column = 0; if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true); bapp_flush_screen(p_app); } } break; case eIR_RIGHT: { if (p_gs->column != 1) { p_info = screen_guide_get_info(p_app,p_gs->selection); //bapp_sync(p_app); if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,false); p_gs->column = 1; if (p_info) draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true); bapp_flush_screen(p_app); } } break; #endif case eIR_MENU: /* if entered using the EGP button directly, then need to retune */ if (eSCREEN_NULL == p_screen->last_screen_id) { /* quit directly, retune is needed */ bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]); bapp_enable_cc(p_app, true); if (p_app->system_mute) bapp_audio_do_mute(p_app, false); bapp_audio_mute(p_app, false); } else { /* don't tune if go back to channel scan menu */ } bapp_goto_last_screen(p_app); result = 1; break; case eIR_GUIDE: /* for any IR remote that has EPG button and quit directly, retune is needed */ bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]); bapp_goto_last_screen(p_app); result = 1; break; case eIR_CH_UP: result = screen_guide_move(p_app,p_screen,MAX_GUIDE_ENTRIES); break; case eIR_UP: result = screen_guide_move(p_app,p_screen,1); break; case eIR_CH_DOWN: result = screen_guide_move(p_app,p_screen,-MAX_GUIDE_ENTRIES); break; case eIR_DOWN: result = screen_guide_move(p_app,p_screen,0); break; /* goto detailed EPG screen */ case eIR_0: { /* set current EPG channel entry accordingly */ p_app->chm.cur_epg_ch_num = p_gs->selection; bapp_set_current_screen(p_app, eSCREEN_DETAILED_GUIDE, eSCREEN_GUIDE); result = 1; } break; default: break; } p_gs->event = *p_event; p_gs->repeat_rate = 1; p_gs->repeat_timeout = bos_getticks() + (DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate); } break; case eS_EVENT_IDLE: { if (p_gs->repeat_timeout < bos_getticks()) { /* Handle repeating when key is held down */ if (p_gs->event.type == eS_EVENT_IR) { switch (p_gs->event.id) { case eIR_UP: case eIR_CH_UP: result = screen_guide_move(p_app,p_screen,1); break; case eIR_DOWN: case eIR_CH_DOWN: result = screen_guide_move(p_app,p_screen,0); break; default: break; } } if (p_gs->repeat_rate < MAX_REPEAT_ACCEL) { p_gs->repeat_rate += REPEAT_INC; } p_gs->repeat_timeout = bos_getticks() + (DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate); } if (!result) result = bscreen_default_idle(v_app,v_screen); } break; default: { result = bscreen_default_event(v_app,v_screen,p_event); } break; } return result; } /* Summary: Draw the guide entry */ static void draw_guide_entry(bapp_t *p_app, bscreen_t *p_screen, guide_state_t *p_gs, int idx, chm_info_t *p_info, bool selected) { int x,y,num_chars,w,h,str_y,l_idx; int bkgnd_color = eCOLOR_MED_BLUE; int offset = 4; int guide_width; l_idx = idx; if (p_app->settings.num_channels == 0) return; /* alternate medium and lt blue background */ bkgnd_color = ((l_idx % 2) ? eCOLOR_MED_BLUE : eCOLOR_LT_BLUE); bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+offset,eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * (l_idx % MAX_GUIDE_ENTRIES)), eSCREEN_ACTION_SAFE_WIDTH - (2*offset), eSCREEN_GUIDE_HEIGHT,bkgnd_color); /* String for channel column */ num_chars = snprintf(p_gs->ch_num_str,24,"%d.%d", p_app->settings.ch[idx].major, p_app->settings.ch[idx].minor); num_chars = c_to_uni_str(p_gs->ch_num_str,p_app->tmp_str,num_chars); bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h); /* draw channel number column */ if ( l_idx >= MAX_GUIDE_ENTRIES) l_idx = (l_idx % MAX_GUIDE_ENTRIES); x = eSCREEN_GUIDE_X; y = eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * l_idx); str_y = y + (eSCREEN_GUIDE_HEIGHT - h)/2; guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, str_y, eSCREEN_GUIDE_CH_WIDTH, eSCREEN_GUIDE_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); /* String for channel short name column */ #ifdef CONFIG_CH_HIDDEN /* limit to 4 callsign chars to make room for add/remove checkbox*/ num_chars = utf16_to_uni_str(p_app->settings.ch[idx].ch_name,p_app->tmp_str,4); #else num_chars = utf16_to_uni_str(p_app->settings.ch[idx].ch_name,p_app->tmp_str,MAX_CH_SHORT_NAME_CHARS); #endif if (num_chars == 0) { num_chars = MAX_CH_SHORT_NAME_CHARS; bscreen_get_string(p_app->lang,eTEXT_NA_GUIDE_CH, p_app->tmp_str, &num_chars); } /* draw channel short name column */ x = eSCREEN_GUIDE_CH_NAME_X - 6; bgfx_fill_rect(&p_app->surf,x, y, eSCREEN_GUIDE_CALLSIGN_WIDTH,eSCREEN_GUIDE_HEIGHT,bkgnd_color); guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, str_y, eSCREEN_GUIDE_CALLSIGN_WIDTH + 6, eSCREEN_GUIDE_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); #ifdef CONFIG_CH_HIDDEN #ifdef CONFIG_CH_HIDDEN_CHECKBOX /* add/remove channel checkbox */ { uint16_t check_x = x + eSCREEN_GUIDE_CALLSIGN_WIDTH + eBUTTON_RADIO_BOX_MARGIN_X - 5; uint16_t check_y = y + (eBUTTON_RADIO_BOX_WIDTH / 4); if ((idx < p_app->settings.num_channels) && (!p_app->settings.ch[idx].hidden)) { /* draw BLACK outline */ bgfx_fill_rect(&p_app->surf,check_x,check_y, eBUTTON_RADIO_BOX_WIDTH,eBUTTON_RADIO_BOX_WIDTH,eCOLOR_BLACK); /* draw GREEN checkbox background */ bgfx_fill_rect(&p_app->surf,check_x + eBUTTON_RADIO_BOX_BORDER,check_y + eBUTTON_RADIO_BOX_BORDER, eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER), eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),eCOLOR_NEON_GREEN); /* draw dot in middle for colorblind users */ bgfx_fill_rect(&p_app->surf,check_x + (eBUTTON_RADIO_BOX_WIDTH / 2) - (eBUTTON_RADIO_BOX_DOT_WIDTH / 2), check_y + (eBUTTON_RADIO_BOX_WIDTH / 2) - (eBUTTON_RADIO_BOX_DOT_WIDTH / 2), eBUTTON_RADIO_BOX_DOT_WIDTH, eBUTTON_RADIO_BOX_DOT_WIDTH, eCOLOR_BLACK); } else { /* draw BLACK outline */ bgfx_fill_rect(&p_app->surf,check_x,check_y, eBUTTON_RADIO_BOX_WIDTH,eBUTTON_RADIO_BOX_WIDTH,eCOLOR_BLACK); /* draw WHITE checkbox background */ bgfx_fill_rect(&p_app->surf,check_x + eBUTTON_RADIO_BOX_BORDER,check_y + eBUTTON_RADIO_BOX_BORDER, eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER), eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),eCOLOR_WHITE); } } #else { x += eSCREEN_GUIDE_CALLSIGN_WIDTH; if ((idx < p_app->settings.num_channels) && (!p_app->settings.ch[idx].hidden)) { num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_STORED, p_app->tmp_str, &num_chars); } else { num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_SKIPPED, p_app->tmp_str, &num_chars); } bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h); if (selected && (p_gs->column == 0)) { bbutton_t button; button.text_id = eTEXT_MAX; button.desc_text_id = eTEXT_MAX; button.type = eBUTTON_MENU; button.x = x-offset; button.y = y; button.width = eSCREEN_GUIDE_HIDDEN_WIDTH[p_app->lang]; button.height = eSCREEN_GUIDE_HEIGHT; bscreen_draw_button_str(p_app,&button,selected,0,p_app->tmp_str, num_chars,NULL,0,eFONT_SIZE_SMALL,0); } else { guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, str_y, eSCREEN_GUIDE_HIDDEN_WIDTH[p_app->lang], eSCREEN_GUIDE_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); } } #endif #endif /* String channel name column */ if (p_info) num_chars = c_to_uni_str(p_info->eit_info[EIT_CURRENT].prog_title,p_app->tmp_str,MAX_TITLE_CHARS); else num_chars = 0; if (num_chars == 0) { /* num_chars = snprintf(p_gs->ch_num_str,31,"Channel - %d.%d", */ /* p_app->settings.ch[idx].major,*/ /* p_app->settings.ch[idx].minor);*/ /* num_chars = c_to_uni_str(p_gs->ch_num_str,p_app->tmp_str,num_chars);*/ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars); } else { if (num_chars > 18) { num_chars = 18; } } p_app->tmp_str[num_chars] = 0; #ifdef CONFIG_CH_HIDDEN x = eSCREEN_GUIDE_CUR_X[p_app->lang]; guide_width = eSCREEN_GUIDE_NAME_WIDTH[p_app->lang]; #else x = eSCREEN_GUIDE_CUR_X; guide_width = eSCREEN_GUIDE_NAME_WIDTH; #endif bgfx_fill_rect(&p_app->surf,x-1, y-1, guide_width + 2,eSCREEN_GUIDE_HEIGHT + 2,bkgnd_color); if (selected && (p_gs->column == 1)) { bbutton_t button; button.text_id = eTEXT_MAX; button.desc_text_id = eTEXT_MAX; button.type = eBUTTON_MENU; button.x = x-offset; button.y = y; button.width = guide_width+offset; button.height = eSCREEN_GUIDE_HEIGHT; bscreen_draw_button_str(p_app,&button,selected,0,p_app->tmp_str, num_chars,NULL,0,eFONT_SIZE_SMALL,0); } else { /* draw channel name column */ guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, str_y, guide_width, eSCREEN_GUIDE_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); } /* String for current column */ if (p_info) num_chars = c_to_uni_str(p_info->eit_info[EIT_NEXT].prog_title,p_app->tmp_str,MAX_TITLE_CHARS); else num_chars = 0; if (num_chars == 0) { num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars); } else { /* changed from 16 to 17 to fix text in the middle issue */ if (num_chars > 17) { num_chars = 17; } } p_app->tmp_str[num_chars] = 0; /* draw channel column */ x = eSCREEN_GUIDE_NEXT_X; bgfx_fill_rect(&p_app->surf,x, y, guide_width,eSCREEN_GUIDE_HEIGHT,bkgnd_color); guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, str_y, guide_width, eSCREEN_GUIDE_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); } /* Summary: Get the guide info for this entry. */ static chm_info_t* screen_guide_get_info(bapp_t *p_app, int idx) { if (idx < 0 || idx >= p_app->settings.num_channels) { return NULL; } return &(p_app->chm.p_info[idx]); } /* Summary: Guide screen drawing function */ void bscreen_guide_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; guide_state_t *p_gs; unsigned int num_chars; chm_info_t *p_info; int idx, w, h; p_gs = (guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); bscreen_draw_background(v_app, &p_app->surf, p_screen->top_banner_height); /* draw title */ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,p_screen->title_text_id, p_app->tmp_str, &num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_LARGE], eMENU_TITLE_TEXT_X, eMENU_TITLE_TEXT_Y, eMENU_TITLE_TEXT_WIDTH, eMENU_TITLE_TEXT_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); /* draw progress text */ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_GUIDE_DL_PROGRESS, p_app->tmp_str, &num_chars); bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], ePROGRESS_GUIDE_X - w - 7, ePROGRESS_GUIDE_TEXT_Y - 4, w + 3, ePROGRESS_GUIDE_TEXT_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,100); bscreen_draw_progress(v_app, ePROGRESS_GUIDE_X, ePROGRESS_GUIDE_Y, ePROGRESS_GUIDE_WIDTH, ePROGRESS_GUIDE_HEIGHT, eBUTTON_VOL_PROGRESS_BORDER, eCOLOR_WHITE, eCOLOR_DRK_BLUE, p_gs->update_progress, 100); /* draw column header bar */ bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+4, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22, eSCREEN_ACTION_SAFE_WIDTH-8,eINFO_AREA_HEIGHT - 6,eCOLOR_DRK_BLUE); /* draw column header */ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_GUIDE_HEADER, p_app->tmp_str, &num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eSCREEN_GUIDE_X, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16, eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); if (p_app->settings.num_channels > 0) { /* Draw the guide entries */ for (idx = p_gs->offset; idx < GUIDE_MIN(p_app->settings.num_channels, (p_gs->offset + MAX_GUIDE_ENTRIES)); ++idx) { p_info = screen_guide_get_info(p_app,idx); if (p_info) { draw_guide_entry(p_app,p_screen,p_gs, idx,p_info, (idx == p_gs->selection) ? true : false); } } } else { int w = 0; int h = 0; /* No channels in channel map so show "No Programs Available" */ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars); bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eSCREEN_GUIDE_X+((eWIDTH-(2*eSCREEN_GUIDE_X))/2)-(w/2), eSCREEN_ACTION_SAFE_Y + eSCREEN_ACTION_SAFE_HEIGHT/2, w+5, h, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); } draw_navigation_hints(v_app, v_screen); } /* Summary: Change to next channel's EPG */ int screen_detailed_guide_move_channel(bapp_t *p_app, bscreen_t *p_screen, int up) { /* check to make sure there are at least 2 channels to move channel up or down */ if (p_app->settings.num_channels < 2) return 1; /* if moving channel up */ if (up > 0) { p_app->chm.cur_epg_ch_num--; if (p_app->chm.cur_epg_ch_num < 0) p_app->chm.cur_epg_ch_num = p_app->settings.num_channels - 1; } else { p_app->chm.cur_epg_ch_num++; } /* remember it so that when go back to GUIDE screen, the current viewed EPG entry will be reflected accordingly */ p_app->chm.cur_epg_ch_num %= p_app->settings.num_channels; bscreen_detailed_guide_draw((void *)p_app, (void *)p_screen); return 1; } /* Summary: Detail Guide handling. return 0 if no redrawing should be done. */ int screen_detailed_guide_move(bapp_t *p_app, bscreen_t *p_screen, int up) { int start_idx,end_idx,num_disp,result =0; guide_state_t *p_gs; p_gs = (guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); start_idx = p_gs->offset; end_idx = GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + (MAX_GUIDE_ENTRIES - 1))); num_disp = (end_idx - start_idx + 1); /* If moving selection up */ if (up > 0) { if (p_gs->selection == 0) { /* already at top */ } else { /* jump one page up */ start_idx -= MAX_GUIDE_ENTRIES; p_gs->selection -= MAX_GUIDE_ENTRIES; if (start_idx < 0) { start_idx = 0; p_gs->selection = 0; } p_gs->offset = start_idx; result = 1; } } else /* moving selection down */ { if (p_gs->selection >= (MAX_EIT_NUM - 1)) { /* already at bottom */ } else { /* jump one page down */ p_gs->offset += MAX_GUIDE_ENTRIES; p_gs->selection += MAX_GUIDE_ENTRIES; if (p_gs->offset >= MAX_EIT_NUM) { p_gs->offset -= MAX_GUIDE_ENTRIES; p_gs->selection = MAX_EIT_NUM - 1; } result = 1; } } return result; } #if 0 /* * Summary: * Detailed Guide draw function. */ static void screen_detailed_guide_handle_redraw(bapp_t *p_app, bscreen_t *p_screen,detailed_guide_state_t *p_gs, int idx) { chm_info_t *p_info; int start_idx,end_idx; start_idx = p_gs->offset; end_idx = GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + (MAX_GUIDE_ENTRIES - 1))); if ((idx < start_idx) || (idx > end_idx)) { /* not in the page */ return; } p_info = screen_guide_get_info(p_app,idx); if (p_info) { draw_detailed_guide_entry(p_app,p_screen,p_gs, idx,p_info,(0 == idx) ? true : false); bapp_flush_screen(p_app); } } #endif /* Summary: Detailed Guide event handling return result; */ int screen_detailed_guide_event(void *v_app, void *v_screen, bscreen_event_t *p_event) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; detailed_guide_state_t *p_gs; int result = 0; bapp_ch_t *pch; p_gs = (detailed_guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); switch (p_event->type) { case eS_EVENT_SETUP: { bscreen_default_setup(v_app,v_screen); /* always start from current EPG time which is the first entry in EIT array */ p_gs->selection = 0; p_gs->offset = 0; /* note that the p_gs->ch_num has been set in the guide_event */ result = 1; /* always handle event */ /* remember current settings in case need to save them */ pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num]; p_gs->skip = pch->skip; p_gs->favorite = pch->favorite; p_gs->save = false; } break; case eS_EVENT_REDRAW: { //screen_detailed_guide_handle_redraw(p_app,p_screen,p_gs, p_gs->offset); result = 1; } break; case eS_EVENT_IR: { switch (p_event->id) { case eIR_MENU: case eIR_GUIDE: bapp_goto_last_screen(p_app); pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num]; if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) { p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip; p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite; p_gs->save = true; } if (p_gs->save) p_app->settings_dirty |= DIRTY_CHANNEL_MAP; result = 1; break; case eIR_UP: result = screen_detailed_guide_move(p_app,p_screen,true); break; case eIR_DOWN: result = screen_detailed_guide_move(p_app,p_screen,false); break; case eIR_CH_DOWN: pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num]; if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) { p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip; p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite; p_gs->save = true; } result = screen_detailed_guide_move_channel(p_app, p_screen, true); /* remember current settings in case need to save them */ pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num]; p_gs->skip = pch->skip; p_gs->favorite = pch->favorite; break; case eIR_CH_UP: if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) { p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip; p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite; p_gs->save = true; } result = screen_detailed_guide_move_channel(p_app, p_screen, false); /* remember current settings in case need to save them */ pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num]; p_gs->skip = pch->skip; p_gs->favorite = pch->favorite; break; case eIR_0: /* toggle skip */ p_gs->skip = !p_gs->skip; bscreen_detailed_guide_options_draw(v_app, v_screen); bapp_flush_screen(p_app); break; case eIR_8: /* toggle favorite */ p_gs->favorite = !p_gs->favorite; bscreen_detailed_guide_options_draw(v_app, v_screen); bapp_flush_screen(p_app); break; default: break; } } break; case eS_EVENT_IDLE: { result = bscreen_default_idle(v_app,v_screen); } break; default: { result = bscreen_default_event(v_app,v_screen,p_event); } break; } return result; } /* Summary: Draw detailed guide entry */ static void draw_detailed_guide_entry(bapp_t *p_app, bscreen_t *p_screen, detailed_guide_state_t *p_gs,int idx, chm_info_t *p_info, bool selected) { int x,y,num_chars,l_idx = idx; int bkgnd_color; int offset = 4; bool dst; unsigned utc_time; b_tm s_tm; if (p_app->settings.num_channels == 0) { /* no channel, shouldn't be called in the first place */ return; } if (idx >= MAX_EIT_NUM) { /* out of range? */ return; } /* alternate medium and light blue background */ bkgnd_color = ((l_idx % 2) ? eCOLOR_MED_BLUE : eCOLOR_LT_BLUE); bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+offset,eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * (l_idx % MAX_GUIDE_ENTRIES)), eSCREEN_ACTION_SAFE_WIDTH - (2*offset), eSCREEN_GUIDE_HEIGHT,bkgnd_color); if (l_idx >= MAX_GUIDE_ENTRIES) l_idx = (l_idx % MAX_GUIDE_ENTRIES); x = eSCREEN_GUIDE_X; y = eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * l_idx); if (0 == p_info->eit_info[EIT_CURRENT].start_time || 0 == p_info->eit_info[EIT_CURRENT].length) { /* just show no data in first entry */ if (selected) { num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, y, eBANNER_START_END_TIME_WIDTH, eBANNER_START_END_TIME_HEIGHT, p_app->tmp_str, num_chars, selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0); } return; } /* draw time range column */ num_chars = MAX_TIME_STR; if (chm_get_time_info(&p_app->chm,&utc_time,&offset,&dst) == 0) { utc_time += offset; utctime(utc_time,&s_tm); /* draw program start/end time if exists */ if ((p_info->eit_info[idx].start_time > 0) && (p_info->eit_info[idx].length > 0)) { unsigned char prog_time_str[MAX_TIME_STR * 2]; unsigned char prog_start_time_str[MAX_TIME_STR]; unsigned char prog_end_time_str[MAX_TIME_STR]; b_tm tm_start; b_tm tm_end; if (dst) { offset += 3600; /* utc_time is already offset for dst but offset is not */ } utctime(p_info->eit_info[idx].start_time + offset, &tm_start); if (tm_start.tm_hour >= 12) { if (tm_start.tm_hour > 12) tm_start.tm_hour -= 12; snprintf(prog_start_time_str,MAX_TIME_STR,"%02d:%02dPM",tm_start.tm_hour,tm_start.tm_min); } else { if (tm_start.tm_hour == 0) tm_start.tm_hour = 12; snprintf(prog_start_time_str,MAX_TIME_STR,"%02d:%02dAM",tm_start.tm_hour,tm_start.tm_min); } utctime(p_info->eit_info[idx].start_time + p_info->eit_info[idx].length + offset, &tm_end); if (tm_end.tm_hour >= 12) { if (tm_end.tm_hour > 12) tm_end.tm_hour -= 12; snprintf(prog_end_time_str,MAX_TIME_STR,"%02d:%02dPM",tm_end.tm_hour,tm_end.tm_min); } else { if (tm_end.tm_hour == 0) tm_end.tm_hour = 12; snprintf(prog_end_time_str,MAX_TIME_STR,"%02d:%02dAM",tm_end.tm_hour,tm_end.tm_min); } snprintf(prog_time_str, (MAX_TIME_STR * 2), "%s-%s",prog_start_time_str,prog_end_time_str); num_chars = MAX_TIME_STR * 2; num_chars = c_to_uni_str(prog_time_str,p_app->tmp_str,num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, y, eBANNER_START_END_TIME_WIDTH, eBANNER_START_END_TIME_HEIGHT, p_app->tmp_str, num_chars, selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0); /* draw program title */ num_chars = c_to_uni_str(p_info->eit_info[idx].prog_title,p_app->tmp_str,MAX_TITLE_CHARS); if (num_chars > 0) { if (num_chars > 40) num_chars = 30; x = eSCREEN_DETAILED_GUIDE_X; text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, y, eSCREEN_DETAILED_GUIDE_WIDTH, eBANNER_TITLE_HEIGHT, p_app->tmp_str, num_chars, (selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE),eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0); } } } } /* Summary: Channel Info (skip/fav) drawing function */ void bscreen_detailed_guide_options_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; detailed_guide_state_t *p_gs; unsigned int num_chars; int w,h,x; char ch_num_str[24]; p_gs = (detailed_guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); x = 250; /* clear previous one */ bgfx_fill_rect(&p_app->surf,x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22, eSCREEN_ACTION_SAFE_WIDTH - 8 -x, 20, eCOLOR_DRK_BLUE); /* English translation is same as Spanish, so hardcoding it */ num_chars = snprintf(ch_num_str,24,"%s", "Skip"); num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars); if (p_gs->skip) { text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 17, 60, eINFO_AREA_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_RED,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW, 0); } if (p_gs->favorite) { bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h); x += (w + 10); /* English translation is same as Spanish, so hardcoding it */ num_chars = snprintf(ch_num_str,24,"%s", "Fav"); num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 17, w + 6, eINFO_AREA_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_RED,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW, 0); } } /* Summary: Guide screen drawing function */ void bscreen_detailed_guide_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; detailed_guide_state_t *p_gs; unsigned int num_chars; chm_info_t *p_info; int i,w,h; char ch_num_str[24]; p_gs = (detailed_guide_state_t*)p_screen->local_state; BDBG_ASSERT(p_gs); bscreen_draw_background(v_app, &p_app->surf, p_screen->top_banner_height); /* draw title */ num_chars = SCREEN_MAX_STR_WIDTH; bscreen_get_string(p_app->lang,p_screen->title_text_id, p_app->tmp_str, &num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_LARGE], eMENU_TITLE_TEXT_X, eMENU_TITLE_TEXT_Y, eMENU_TITLE_TEXT_WIDTH, eMENU_TITLE_TEXT_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); /* draw background */ bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+4, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22, eSCREEN_ACTION_SAFE_WIDTH-8,eINFO_AREA_HEIGHT - 6,eCOLOR_DRK_BLUE); /* draw channel name */ i = p_app->chm.cur_epg_ch_num; p_info = screen_guide_get_info(p_app, i); if (p_info) { /* draw channel number */ num_chars = snprintf(ch_num_str,24,"%d.%d", p_app->settings.ch[i].major, p_app->settings.ch[i].minor); num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eSCREEN_GUIDE_X, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16, eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); /* find x location to draw channel name */ bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h); num_chars = MAX_CH_NAME_CHARS+1; num_chars = utf16_to_uni_str(p_app->settings.ch[i].ch_name,p_app->tmp_str,num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eSCREEN_GUIDE_X + w + 5, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16, eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING); /* draw skip and favorite */ bscreen_detailed_guide_options_draw(v_app, v_screen); /* Draw detailed guide entries for given channel */ for (i = p_gs->offset; i < GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + MAX_GUIDE_ENTRIES)); i++) { draw_detailed_guide_entry(p_app,p_screen,p_gs,i, p_info, (0 == i) ? true : false); } } else { /* should we draw no data */ } draw_navigation_hints(v_app, v_screen); }