/*************************************************************************** * Copyright (c) 2003-2006, 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: * * $brcm_Log: $ * ***************************************************************************/ #include "bapp.h" #include "bsettop_display.h" #include "bstd.h" #include "bapp_util.h" #include "ministd.h" #include "bgfx.h" #include "chan_mgr.h" #include "bscreen_status_str.c" #include "bscreen.h" BDBG_MODULE(bscreen_status); /* Register software module with debug interface */ extern bool g_disable_fcc; static bool scan_channels = false; /* whether scan the channels or not */ #define MAX_TSTR_LEN 128 typedef enum dbg_layout_t { eINFO_X = eSCREEN_ACTION_SAFE_X, eINFO_STATUS_X = eSCREEN_ACTION_SAFE_X + 20, eINFO_STATUS_Y = eSCREEN_ACTION_SAFE_Y, eINFO_COL_WIDTH = eSCREEN_ACTION_SAFE_WIDTH/2, eINFO_COL_LABEL_WIDTH = eINFO_COL_WIDTH, eINFO_ROW_HEIGHT = 24, eINFO_HELP_Y = (eSCREEN_ACTION_SAFE_HEIGHT + eSCREEN_ACTION_SAFE_Y - eINFO_ROW_HEIGHT), eCH_MAP_START_X = eSCREEN_ACTION_SAFE_X, eCH_MAP_START_Y = eSCREEN_ACTION_SAFE_Y, eCH_MAP_HDR_Y = (eSCREEN_ACTION_SAFE_Y + eINFO_ROW_HEIGHT), eCH_MAP_ROW_Y = eCH_MAP_HDR_Y, eCH_MAP_COL_WIDTH = (eSCREEN_ACTION_SAFE_WIDTH/6), eCH_MAP_ROW_HEIGHT = 24, eCH_MAP_NUM_ROW = (((eSCREEN_ACTION_SAFE_HEIGHT - 3*eINFO_ROW_HEIGHT)/eCH_MAP_ROW_HEIGHT) - 1), eDIAG_ROW_HEIGHT = 24, eDIAG_START_X = eSCREEN_ACTION_SAFE_X, eDIAG_MENU_X = (eDIAG_START_X + 20), eDIAG_START_Y = eSCREEN_ACTION_SAFE_Y, eDIAG_HELP_Y = (eSCREEN_ACTION_SAFE_Y + eSCREEN_ACTION_SAFE_HEIGHT - eDIAG_ROW_HEIGHT), eDIAG_COL_WIDTH = (eSCREEN_ACTION_SAFE_WIDTH), /* customize frequencies support */ eMENU_FREQUENCY_X = (eMENU_TITLE_TEXT_X), eMENU_FREQUENCY_Y = (eMENU_TITLE_DESC_TEXT_Y+40), eMENU_FREQUENCY_WIDTH = 300, eMENU_FREQUENCY_HEIGHT= 33, eMENU_FREQ_ROW_START_Y= (eMENU_FREQUENCY_Y+45), eMENU_FREQ_COLUMN_HEIGHT= 30, eMENU_FREQ_COLUMN_WIDTH= (eSCREEN_ACTION_SAFE_WIDTH-eMENU_TITLE_TEXT_X)/5, }dbg_layout_t; typedef enum sys_info_state_t { eSYS_CODE_0, eSYS_CODE_1, eSYS_CODE_2, eSYS_CODE_MAX, }sys_info_state_t; typedef struct sys_info_t { sys_info_state_t state; unsigned int code; }sys_info_t; static sys_info_t s_sys_info = { eSYS_CODE_0, 0}; static char ts_str[MAX_TSTR_LEN + 1]; /* Summary: Handle special debug commands for test purposes or diagnostics. */ static void bscreen_sys_info_handler(bapp_t *p_app,bscreen_t *p_screen, bIR_codes_t code) { static unsigned int s_timeout = 0; BDBG_WRN(("%s 0x%08x %d\n",__FUNCTION__,s_sys_info.code,s_sys_info.state)); if (s_timeout < bos_getticks()) { s_sys_info.code = 0; s_sys_info.state = 0; } s_sys_info.code |= (code & 0xFF) << (8 * s_sys_info.state); s_sys_info.state++; BDBG_WRN(("%s 0x%08x %d\n",__FUNCTION__,s_sys_info.code,s_sys_info.state)); s_timeout = bos_getticks() + MS_TO_TICKS(BANNER_10_KEY_TIMEOUT); #ifdef BCM_DEBUG if (s_sys_info.state == eSYS_CODE_MAX) { switch (s_sys_info.code) { default: break; } s_sys_info.state = eSYS_CODE_0; s_sys_info.code = 0; } #endif } /* Summary: Return status strings. */ static void bscreen_general_info_str(bapp_t *p_app, bscreen_t *p_screen, int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len, /* On input the max length in words on output the actual size in characters. */ void *data /* User data */ ) { *str_len = 0; switch (text_id) { case 0: strcpy(ts_str,DEF_VENDOR_NAME); *str_len = strlen(ts_str); break; case 1: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%08X",DEF_VENDOR_ID); break; case 2: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d.%d.%d",MAJOR_VERSION,MINOR_VERSION,SUB_VERSION); break; case 3: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s", __DATE__); break; } if (*str_len) { *str_len = c_to_uni_str(ts_str,p_uni_str,*str_len); } } /* Summary: Return tunre status strings for diagnostic */ static void bscreen_tuner_status_str(bapp_t *p_app, bscreen_t *p_screen, int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len, /* On input the max length in words on output the actual size in characters. */ void *data /* User data */ ) { uint32_t freq_mhz, freq_fraction; bapp_ch_t *pch; *str_len = 0; if (NULL == (pch = bapp_is_channel_valid(p_app))) { BDBG_WRN(("No tuner information")); return; } freq_mhz = pch->frequency_khz / 1000; freq_fraction = (pch->frequency_khz % 1000); switch (text_id) { case 0: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%03d.%03d", freq_mhz, freq_fraction); break; case 1: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s", p_app->tuner_status.lock ? "yes" : "no"); break; case 2: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d%", p_app->power_level); break; case 3: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d (%d.%d dB)", p_app->tuner_status.snr, p_app->tuner_status.snr/256, ((p_app->tuner_status.snr % 256) * 100)/256); break; case 4: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d%", p_app->tuner_status.PreRS); break; case 5: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d", p_app->tuner_status.agcIntLevel); break; case 6: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d", p_app->tuner_status.correctedCount); break; default: break; } if (*str_len) { *str_len = c_to_uni_str(ts_str,p_uni_str,*str_len); } } /* Summary: Return status strings. */ static void bscreen_ch_status_str(bapp_t *p_app, bscreen_t *p_screen, int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len, /* On input the max length in words on output the actual size in characters. */ void *data /* User data */ ) { bapp_ch_t *pch; *str_len = 0; if (NULL == (pch = bapp_is_channel_valid(p_app))) { BDBG_WRN(("No channel status inforamtion")); return; } switch (text_id) { case 0: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d.%d",pch->major, pch->minor); break; case 1: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s",pch->psi ? "PSI" : "VCT"); break; case 2: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04x", pch->pcr_pid); break; case 3: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04x", pch->video_pid); break; case 4: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s",pch->hidden ? "yes" : "no"); break; case 5: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d", pch->program_num); break; case 6: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d",pch->num_audio); break; case 7: if (pch->audio_lang[0][0]) { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X [%c%c%c] %s", pch->audio_pid[0], pch->audio_lang[0][0], pch->audio_lang[0][1], pch->audio_lang[0][2], (pch->cur_audio == 0) ? "*" : " "); } else { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X %s", pch->audio_pid[0], (pch->cur_audio == 0) ? "*" : " "); } break; case 8: if (pch->audio_lang[1][0]) { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X [%c%c%c] %s",pch->audio_pid[1], pch->audio_lang[1][0], pch->audio_lang[1][1], pch->audio_lang[1][2], (pch->cur_audio == 1) ? "*" : " "); } else { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X %s", pch->audio_pid[1], (pch->cur_audio == 1) ? "*" : " "); } break; case 9: if (MAX_AUDIO_PIDS > 2) { if (pch->audio_lang[2][0]) { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X [%c%c%c] %s",pch->audio_pid[2], pch->audio_lang[2][0], pch->audio_lang[2][1], pch->audio_lang[2][2], (pch->cur_audio == 2) ? "*" : " "); } else { *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X %s", pch->audio_pid[2], (pch->cur_audio == 2) ? "*" : " "); } } break; case 10: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s", p_app->is_muted ? "yes" : "no"); break; default: break; } if (*str_len) { *str_len = c_to_uni_str(ts_str,p_uni_str,*str_len); } } /* Summary: Use the this function to get a UNI string. */ static void bscreen_decoder_status_str(bapp_t *p_app, bscreen_t *p_screen, int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len, /* On input the max length in words on output the actual size in characters. */ void *data) { static bdecode_status status; static baudio_decode_status audio_status; if (NULL == bapp_is_channel_valid(p_app)) { return; } *str_len = 0; memset(&status, 0, sizeof(status)); memset(&audio_status, 0, sizeof(audio_status)); bdecode_get_status(p_app->decode,&status); baudio_decode_get_status(p_app->audio, &audio_status); switch (text_id) { case 0: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%04X, 0x%04X, 0x%04X",status.vPID,audio_status.pid,status.pcrPID); break; case 1: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%08X/0x%08X",status.video_stc,status.video_pts); break; case 2: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"0x%08X/0x%08X",audio_status.stc,audio_status.pts); break; case 3: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d",(int)audio_status.pts - (int)status.video_pts); break; case 4: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d",(int)audio_status.stc-(int)audio_status.pts); break; case 5: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d",(int)status.video_stc-(int)status.video_pts); break; case 6: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d/%d,%d/%d",audio_status.fifo_depth,audio_status.fifo_size,status.video_fifo_depth,status.video_fifo_size); break; case 7: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d:%d(%s,%d)",status.source_width,status.source_height,(status.bStreamProgressive ? "P" : "I"),status.video_aspect_ratio); break; case 8: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d",p_app->tune_ms); break; case 9: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%d/%d/%d",p_app->si_ms,TICKS_TO_MS(status.seq_ticks),TICKS_TO_MS(status.first_pts_ticks)); break; case 10: *str_len = snprintf(ts_str,MAX_TSTR_LEN,"%s", "stereo"); break; default: break; } if (*str_len) { *str_len = c_to_uni_str(ts_str,p_uni_str,*str_len); } } /* Summary: Status screen drawing function. */ static void bscreen_diag_list_draw(bapp_t *p_app, bscreen_t *p_screen, const unsigned char *p_title_str, const unsigned char *p_label_str[], get_str_t get_str_fcn, bool track_selection ) { uint16_t x,y,y_off; unsigned int num_chars = 0; bcolor_idx_t text_color; int i; x = eINFO_STATUS_X; y = eINFO_STATUS_Y; i = 0; y += eINFO_ROW_HEIGHT + 6; while (*(p_label_str[i]) != '\0') { text_color = eCOLOR_WHITE; y_off = y + (i * eINFO_ROW_HEIGHT); if ((y_off + eINFO_ROW_HEIGHT) >= eHEIGHT) { BDBG_WRN(("%s too many rows %d, y = %d\n",__FUNCTION__,i,y_off)); break; } bgfx_fill_rect(&p_app->surf,x,y_off,eWIDTH - x,eINFO_ROW_HEIGHT,eCOLOR_BLACK); num_chars = strlen(p_label_str[i]); num_chars = c_to_uni_str((unsigned char*)p_label_str[i],p_app->tmp_str,num_chars); if (track_selection && (i == p_screen->local_state)) { text_color = eCOLOR_DK_YELLOW; } text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], x, y_off, eINFO_COL_LABEL_WIDTH, eINFO_ROW_HEIGHT, p_app->tmp_str, num_chars, text_color,0); num_chars = SCREEN_MAX_STR_WIDTH; get_str_fcn(p_app,p_screen,i,p_app->tmp_str, &num_chars,NULL); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], x + eINFO_COL_LABEL_WIDTH, y_off, eWIDTH - x - eINFO_COL_WIDTH, eINFO_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); i++; } } /* Summary: Status screen drawing function. */ static void bscreen_diag_draw(bapp_t *p_app, bscreen_t *p_screen, const unsigned char *p_title_str, const unsigned char *p_help_str, const unsigned char *p_label_str[], get_str_t get_str_fcn, bool track_selection ) { uint16_t x,y; unsigned int num_chars = 0; int page; page = p_screen->local_state; x = eINFO_X; y = eINFO_STATUS_Y; bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_BLACK); bgfx_fill_rect(&p_app->surf,x,y,eWIDTH - x,eINFO_ROW_HEIGHT,eCOLOR_BLACK); num_chars = strlen(p_title_str); num_chars = c_to_uni_str((unsigned char*)p_title_str,p_app->tmp_str,num_chars); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_MED], x, y, eSCREEN_ACTION_SAFE_WIDTH, eINFO_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); bscreen_diag_list_draw(p_app,p_screen,p_title_str,p_label_str,get_str_fcn,track_selection); num_chars = strlen(p_help_str); num_chars = c_to_uni_str((unsigned char*)p_help_str,p_app->tmp_str,num_chars); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], x, eINFO_HELP_Y, eSCREEN_ACTION_SAFE_WIDTH, eINFO_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); } int bscreen_diag_event(bapp_t *p_app, bscreen_t *p_screen, bscreen_event_t *p_event, void (*draw_fcn)(void *v_app, void *v_screen), int refresh) { int result = 0; static int cnt = 0; switch (p_event->type) { case eS_EVENT_SETUP: p_screen->local_state = 0; bapp_enable_cc(p_app, false); bapp_audio_do_mute(p_app, true); bapp_video_mute(p_app, true); scan_channels = false; result = 1; break; case eS_EVENT_SETUP_DONE: if (eSCREEN_TUNER_STATUS == p_app->screen_id) { p_app->chm_cmd.cmd_id = eCHM_CHECK_SIGNAL; chm_cmd(&p_app->chm,&p_app->chm_cmd); p_app->check_signal = true; } result = 1; break; case eS_EVENT_IDLE: if (refresh <= 0) break; if (cnt++ == 20) { cnt = 0; draw_fcn(p_app,p_screen); result = 1; } break; case eS_EVENT_IR: { BDBG_WRN(("%s:%d 0x%02x(%s)\n",__FUNCTION__,__LINE__,p_event->id,(p_event->id & 0x40000000) ? "up" : "down")); switch (p_event->id) { case eIR_INFO: if (eSCREEN_TUNER_STATUS == p_app->screen_id) { p_app->chm_cmd.cmd_id = eCHM_INFO; chm_cmd(&p_app->chm,&p_app->chm_cmd); p_app->check_signal = false; } /* only set screen if there is signal, otherwise there will be a flash of video before entering to no signal screen */ if (bapp_get_signal_status(p_app)) { bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX); bapp_enable_cc(p_app, true); bapp_audio_do_mute(p_app, false); bapp_video_mute(p_app, false); } result = 1; break; case eIR_MENU: if (eSCREEN_TUNER_STATUS == p_app->screen_id) { p_app->chm_cmd.cmd_id = eCHM_CANCEL; chm_cmd(&p_app->chm,&p_app->chm_cmd); p_app->check_signal = false; } bapp_set_current_screen(p_app, eSCREEN_DIAG_MENU, eSCREEN_MAX); result = 1; break; default: break; } break; } break; default: result = bscreen_default_event(p_app,p_screen,p_event); break; } return result; /* always handle event */ } /* Summary: Status screen drawing function. */ void bscreen_sys_info_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; bscreen_diag_draw(p_app,p_screen,s_main_menu[eMM_IDX_GENERAL_INFO], (unsigned char *)s_diag_help_simple,s_general_info_str, (get_str_t)bscreen_general_info_str,false); } /* Summary: Status screen event handling function. */ int bscreen_sys_info_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; return bscreen_diag_event(p_app,p_screen,p_event,bscreen_sys_info_draw,-1); } /* Summary: Status screen drawing function. */ void bscreen_tuner_status_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; bscreen_diag_draw(p_app,p_screen,s_main_menu[eMM_IDX_TUNER_STATUS], (unsigned char *)s_diag_help_default,s_tuner_status_str, (get_str_t)bscreen_tuner_status_str,false); } /* Summary: Status screen event handling function. */ int bscreen_tuner_status_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; return bscreen_diag_event(p_app,p_screen,p_event,bscreen_tuner_status_draw,1); } /* Summary: Status screen drawing function. */ void bscreen_decoder_status_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; bscreen_diag_draw(p_app,p_screen,s_main_menu[eMM_IDX_DECODER_STATUS], (unsigned char *)s_diag_help_simple,s_decoder_status_str, (get_str_t)bscreen_decoder_status_str,false); } /* Summary: Status screen event handling function. */ int bscreen_decoder_status_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; return bscreen_diag_event(p_app,p_screen,p_event,bscreen_decoder_status_draw,1); } /* Summary: Status screen drawing function. */ void bscreen_ch_status_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; bscreen_diag_draw(p_app,p_screen,s_main_menu[eMM_IDX_CH_STATUS], (unsigned char *)s_diag_help_in_use,s_ch_status_str, (get_str_t)bscreen_ch_status_str,false); } /* Summary: Status screen event handling function. */ int bscreen_ch_status_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; return bscreen_diag_event(p_app,p_screen,p_event,bscreen_ch_status_draw,1); } int bscreen_diag_menu_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; int result = 0; switch (p_event->type) { case eS_EVENT_SETUP: // Don't reset so we return with same item selectd p_screen->local_state = 0; s_sys_info.state = eSYS_CODE_0; bapp_enable_cc(p_app, 0); bapp_audio_do_mute(p_app, true); bapp_video_mute(p_app, true); result = 1; break; case eS_EVENT_IDLE: { /* Do anything that requires periodic action here */ } break; case eS_EVENT_IR: { BDBG_WRN(("%s:%d 0x%02x(%s)\n",__FUNCTION__,__LINE__,p_event->id,(p_event->id & 0x40000000) ? "up" : "down")); switch (p_event->id) { case eIR_CH_UP: case eIR_UP: p_screen->local_state--; if ((int)p_screen->local_state <= 0) p_screen->local_state = eMM_IDX_NUM - 1; result = 1; break; case eIR_CH_DOWN: case eIR_DOWN: p_screen->local_state++; if (p_screen->local_state >= eMM_IDX_NUM) p_screen->local_state = 0; result = 1; break; case eIR_SELECT: switch (p_screen->local_state) { case 0: bapp_set_current_screen(p_app, eSCREEN_SYS_INFO, eSCREEN_MAX); result = 1; break; case 1: bapp_set_current_screen(p_app, eSCREEN_TUNER_STATUS, eSCREEN_MAX); result = 1; break; case 2: bapp_set_current_screen(p_app, eSCREEN_CH_STATUS, eSCREEN_MAX); result = 1; break; case 3: bapp_set_current_screen(p_app, eSCREEN_DECODER_STATUS, eSCREEN_MAX); result = 1; break; case 4: bapp_set_current_screen(p_app, eSCREEN_FREQUENCY_CONFIGURE, eSCREEN_MAX); result = 1; break; } break; case eIR_INFO: if (scan_channels) { if (p_app->scan_in_progress) { bos_sleep(1000); } p_app->chm.force_tune = true; bapp_tune(p_app); } bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX); bapp_audio_do_mute(p_app, false); bapp_video_mute(p_app, false); bapp_enable_cc(p_app, true); result = 1; break; case eIR_0: case eIR_1: case eIR_2: case eIR_3: case eIR_4: case eIR_5: case eIR_6: case eIR_7: case eIR_8: case eIR_9: bscreen_sys_info_handler(p_app,p_screen,p_event->id); break; } } break; default: result = bscreen_default_event(v_app,v_screen,p_event); break; } return result; /* always handle event */ } /* Summary: Diag menu screen drawing function */ void bscreen_diag_menu_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; unsigned int num_chars; int yoff,row,i; bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_BLACK); num_chars = strlen(s_menu_title); num_chars = c_to_uni_str((unsigned char*)s_menu_title,p_app->tmp_str,num_chars); yoff = eDIAG_START_Y; text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_MED], eDIAG_START_X, yoff, eDIAG_COL_WIDTH, eDIAG_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); yoff += 6; for (row = 0; row < eMM_IDX_NUM; ++row) { yoff += eDIAG_ROW_HEIGHT; num_chars = strlen(s_main_menu[row]); num_chars = c_to_uni_str((unsigned char*)s_main_menu[row],p_app->tmp_str,num_chars); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], eDIAG_MENU_X, yoff, eDIAG_COL_WIDTH, eDIAG_ROW_HEIGHT, p_app->tmp_str, num_chars, (row == p_screen->local_state ? eCOLOR_LT_YELLOW : eCOLOR_WHITE) ,0); } num_chars = strlen(s_menu_help); num_chars = c_to_uni_str((unsigned char*)s_menu_help,p_app->tmp_str,num_chars); /* substitute [1234] to up,down,left or right if any */ for (i = 0; i < num_chars; ++i) { if (p_app->tmp_str[i] == 0x00000031) { p_app->tmp_str[i] = 0x2593;/* up */ } else if (p_app->tmp_str[i] == 0x00000032) { p_app->tmp_str[i] = 0x2502;/* down */ } else if (p_app->tmp_str[i] == 0x00000033) { p_app->tmp_str[i] = 0x2591;/* left */ } else if (p_app->tmp_str[i] == 0x00000034) { p_app->tmp_str[i] = 0x2592;/* right */ } } text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], eDIAG_START_X, eDIAG_HELP_Y, eDIAG_COL_WIDTH, eDIAG_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); } static unsigned int s_user_defined_freq[MAX_USER_FREQ]; static unsigned int s_user_defined_freq_num; static int tmp_cnt, freq_low; void add_user_defined_frequency(int freq_high, int freq_low, int cnt) { int i; int add_index=MAX_USER_FREQ, del_index=MAX_USER_FREQ; unsigned int freq = 0, r=1; freq = freq_high*1000; if (cnt>0) { for (i=0; i<(3-cnt); i++) r *= 10; freq += freq_low*r; } for (i=0; itype == eS_EVENT_SETUP) { p_app->tmp_value = 0; tmp_cnt = -1; freq_low = -1; freq_high = 0; bscreen_default_setup(v_app, v_screen); } else if (p_event->type == eS_EVENT_IR) { switch(p_event->id) { case eIR_LEFT: /* delete */ result = 1; if (freq_low == -1) { if (p_app->tmp_value > 0 && p_app->tmp_value<10) { freq_high = 1; } else if (p_app->tmp_value == 0) { freq_high = 0; } else { freq_high--; } p_app->tmp_value /= 10; } else { if (freq_low == 0) { freq_low = -1; tmp_cnt = -1; } else { tmp_cnt /= 10; freq_low--; } } break; /* RCA IR remote doesn't have Last button, so use ARROW UP button instead */ //case eIR_PRECH: case eIR_UP: result = 1; for (i=0, cnt=0; isettings.num_channels = 0; p_app->cur_ch_num = 0; p_app->settings_dirty = DIRTY_CHANNEL|DIRTY_CHANNEL_MAP|DIRTY_SCREEN; bapp_save_settings(p_app); scan_channels = true; p_app->chm.fe_type = eFREQ_TABLE_USER_DEFINED; bapp_channel_scan(p_app); /* !!! pass through */ case eIR_MENU: result = 1; bapp_goto_last_screen(p_app); break; case eIR_SELECT: result = 1; add_user_defined_frequency(p_app->tmp_value, tmp_cnt, freq_low); freq_low = -1; freq_high = 0; tmp_cnt = -1; p_app->tmp_value = 0; break; case eIR_0: case eIR_1: case eIR_2: case eIR_3: case eIR_4: case eIR_5: case eIR_6: case eIR_7: case eIR_8: case eIR_9: result = 1; if (freq_low == -1) { if (freq_high>4) break; p_app->tmp_value = p_app->tmp_value*10 + p_event->id; if (p_app->tmp_value>0) freq_high++; } else { if (freq_low>=3) break; tmp_cnt = tmp_cnt*10 + p_event->id; freq_low++; } break; case eIR_DOT: case eIR_RIGHT: result = 1; if (freq_low == -1) { freq_low = 0; tmp_cnt = 0; } break; default: result = bscreen_default_event(v_app, v_screen,p_event); break; } } else { result = bscreen_default_event(v_app, v_screen, p_event); } return result; } void bscreen_frequency_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t *)v_app; bscreen_t *p_screen = (bscreen_t *)v_screen; unsigned int num_chars; unsigned char buf[20]; uint16_t x, y, width, height; unsigned int i, remainder, r, cnt, row, column; bgfx_fill_rect(&p_app->surf, 0, 0, eWIDTH, eHEIGHT, eCOLOR_BLACK_65); /* draw title */ num_chars = SCREEN_MAX_STR_WIDTH; num_chars = c_to_uni_str((unsigned char *)s_frequency, 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_WHITE, eCOLOR_BLACK_65, eMENU_TEXT_DROPSHADOW, eMENU_TITLE_TEXT_HEIGHT); /* draw description */ num_chars = SCREEN_MAX_STR_WIDTH; num_chars = c_to_uni_str((unsigned char *)s_frequency_desc, p_app->tmp_str, num_chars); bapp_str_get(p_app->lang,p_screen->desc_text_id, p_app->tmp_str, &num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eMENU_TITLE_DESC_TEXT_X, eMENU_TITLE_DESC_TEXT_Y, eMENU_TITLE_DESC_TEXT_WIDTH, eMENU_TITLE_DESC_TEXT_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK_65, eMENU_TEXT_DROPSHADOW ,eMENU_TITLE_DESC_TEXT_SPACING); num_chars = strlen("Frequency"); num_chars = c_to_uni_str("Frequency", p_app->tmp_str, num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_MED], eMENU_FREQUENCY_X, eMENU_FREQUENCY_Y, eMENU_FREQUENCY_WIDTH, eMENU_FREQUENCY_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE, eCOLOR_BLACK_65, eMENU_TEXT_DROPSHADOW, 0); /* draw user's input */ num_chars = SCREEN_MAX_STR_WIDTH; memset(buf, 0, 20); if (freq_low>0) { num_chars = snprintf(buf, 20, "%d.", p_app->tmp_value); for (r=1,i=0; i<(freq_low-1); i++) r = r*10; remainder = tmp_cnt; for (i=0;i<(freq_low-1); i++) { buf[num_chars] = '0'+remainder/r; num_chars++; remainder = remainder % r; r /= 10; } buf[num_chars] = '0'+remainder; num_chars++; } else if (freq_low == 0) { snprintf(buf, 20, "%d.", p_app->tmp_value); } else { snprintf(buf, 20, "%d", p_app->tmp_value); } num_chars = strlen(buf); num_chars = c_to_uni_str(buf, p_app->tmp_str, num_chars); x = eMENU_FREQUENCY_X+eMENU_FREQUENCY_WIDTH/2; y = eMENU_FREQUENCY_Y; width = eMENU_FREQUENCY_WIDTH/2; height = eMENU_FREQUENCY_HEIGHT; bgfx_draw_text_box_ex(&p_app->surf, &x, &y, &width, &height, p_app->tmp_str, num_chars, p_app->p_font[p_app->lang][eFONT_SIZE_MED], eCOLOR_WHITE, eCOLOR_BLACK_65, eCOLOR_WHITE, 0, 0, 0, 2, 1); num_chars = strlen("MHz"); num_chars = c_to_uni_str("MHz", p_app->tmp_str, num_chars); text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_MED], eMENU_FREQUENCY_X+eMENU_FREQUENCY_WIDTH, eMENU_FREQUENCY_Y + 2, 100, eMENU_FREQUENCY_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE, eCOLOR_BLACK_65, eMENU_TEXT_DROPSHADOW, 0); /* draw user-defined frequency table */ for (row=0,cnt=0,i=0; itmp_str, num_chars); bgfx_draw_text_box_ex(&p_app->surf, &x, &y, &width, &height, p_app->tmp_str, num_chars, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], eCOLOR_WHITE, eCOLOR_BLACK_65, eCOLOR_WHITE, 0, 0, 0, 2, 1); cnt++; } } num_chars = strlen(s_frequency_help); num_chars = c_to_uni_str((unsigned char*)s_frequency_help,p_app->tmp_str,num_chars); for (i = 0; i < num_chars; ++i) { if (p_app->tmp_str[i] == 0x00000031) { p_app->tmp_str[i] = 0x2593;/* up */ } else if (p_app->tmp_str[i] == 0x00000032) { p_app->tmp_str[i] = 0x2502;/* down */ } else if (p_app->tmp_str[i] == 0x00000033) { p_app->tmp_str[i] = 0x2591;/* left */ } else if (p_app->tmp_str[i] == 0x00000034) { p_app->tmp_str[i] = 0x2592;/* right */ } } text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], eINFO_X, eINFO_HELP_Y, eSCREEN_ACTION_SAFE_WIDTH, eINFO_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); } void bapp_user_freq_table_get(bapp_t *p_app, unsigned int *freq_table[], unsigned int *num_freq) { *num_freq = s_user_defined_freq_num; *freq_table = s_user_defined_freq; }