source: svn/trunk/newcon3bcm2_21bu/dta/src/app/ntia/bguide.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 41.1 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2013, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *      Liqun 01/29/2013, Add UI to display more EPG data per customer's request
18 *
19 * $brcm_Log:  $
20 *
21 ***************************************************************************/
22
23#define MAX_GUIDE_ENTRIES   9
24
25#ifdef CONFIG_DVB
26#include "dvb_parser.h"
27#endif
28
29/* Define to test guide drawing and selection control without PSIP guide data */
30/*
31#define STATIC_GUIDE_TEST
32*/
33
34#define GUIDE_MIN(x,y)      ((x < y) ? x : y)
35#define eSCREEN_GUIDE_X                 82
36#define eSCREEN_GUIDE_Y_OFF             130
37#define eSCREEN_GUIDE_HEIGHT            30
38#define eSCREEN_GUIDE_CH_WIDTH          55
39#define eSCREEN_GUIDE_CALLSIGN_WIDTH    90
40#define eSCREEN_GUIDE_CH_NAME_X         138
41#define eSCREEN_GUIDE_CH_NAME_WIDTH     30
42#define eSCREEN_GUIDE_NEXT_X            445
43#define eSCREEN_GUIDE_CUR_X             235
44#define eSCREEN_GUIDE_NAME_WIDTH        196
45#define eSCREEN_GUIDE_SPACING           30
46#define eSCREEN_DETAILED_GUIDE_X                255
47#define eSCREEN_DETAILED_GUIDE_WIDTH    420
48
49#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)
50
51static void draw_guide_entry(bapp_t *p_app, bscreen_t *p_screen, guide_state_t *p_gs, int idx, chm_info_t *p_info, 
52        bool selected);
53static chm_info_t* screen_guide_get_info(bapp_t *p_app, int idx);
54
55static 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, 
56        bool selected);
57
58static void bscreen_detailed_guide_options_draw(void *v_app, void *v_screen);
59
60guide_state_t g_guide_state = 
61{
62        0,
63        0,
64        1,
65        "",
66        { eS_EVENT_MAX, 0, 0},
67        0,
68        0,
69        0
70};
71
72detailed_guide_state_t g_detailed_guide_state =
73{
74    0,
75    0,
76};
77
78/*
79Summary:
80        Guide event handling. return 0 if no redrawing should be done.
81*/
82int screen_guide_move(bapp_t *p_app, bscreen_t *p_screen, int up)
83{
84    int start_idx,end_idx,num_disp,result,old_sel;
85    guide_state_t *p_gs;
86    p_gs = (guide_state_t*)p_screen->local_state;
87    chm_info_t *p_info;
88    chm_info_t *p_old_info;
89    BDBG_ASSERT(p_gs);
90
91    result = 0;
92
93    if (p_app->settings.num_channels < 2)
94        return result;
95
96    start_idx = p_gs->offset;
97    end_idx = GUIDE_MIN((p_app->settings.num_channels - 1), 
98                (p_gs->offset + (MAX_GUIDE_ENTRIES - 1)));
99    num_disp = (end_idx - start_idx + 1);
100
101    old_sel = p_gs->selection;
102    /* If moving selection up */
103    if (up > 0)
104    {
105        if (p_gs->selection == 0)
106        {
107            /* already at top */
108                        p_app->chm.epg_update_ch_num = 0;
109        }
110        else
111        if (up >= MAX_GUIDE_ENTRIES)
112        {
113            /* jump one page up */
114            start_idx -= MAX_GUIDE_ENTRIES;
115            p_gs->selection -= MAX_GUIDE_ENTRIES;
116            if (start_idx < 0)
117            {
118                BDBG_ERR(("start_idx = %d < 0\n", start_idx));
119                start_idx = 0;
120                p_gs->selection = start_idx;
121            }
122
123            p_gs->offset = start_idx;
124                        /* update from top of guild entry of current page */
125                        p_app->chm.cur_ch_num = start_idx;
126                        p_app->chm.epg_update_ch_num = start_idx;
127                        if (p_app->chm.epg_update_ch_num > 0)
128                                p_app->chm.epg_update_ch_num--;
129            result = 1;
130        }
131        else
132        if (p_gs->selection > start_idx)
133        {
134            p_gs->selection--;
135            p_old_info = screen_guide_get_info(p_app,old_sel);
136            p_info = screen_guide_get_info(p_app,p_gs->selection);
137            //bapp_sync(p_app);
138            if (p_info)
139                draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true);
140                        if (p_old_info)
141                draw_guide_entry(p_app,p_screen,p_gs, old_sel,p_old_info,false);
142            bapp_flush_screen(p_app);
143        }
144        else if (start_idx > 0)
145        {
146            start_idx -= MAX_GUIDE_ENTRIES;
147            if (start_idx < 0)
148            {
149                BDBG_ERR(("start_idx = %d < 0\n", start_idx));
150                start_idx = 0;
151                p_gs->selection = start_idx;
152            }
153            p_gs->offset = start_idx;
154            p_gs->selection--;
155                        /* update from top of guild entry of current page */
156                        p_app->chm.cur_ch_num = start_idx;
157            p_app->chm.epg_update_ch_num = start_idx;
158            if (p_app->chm.epg_update_ch_num > 0)
159                p_app->chm.epg_update_ch_num--;
160            result = 1;
161        }
162        else
163        {
164            /* Do nothing */
165        }
166    }
167    else /* moving selection down */
168    {
169        if (p_gs->selection == (p_app->settings.num_channels - 1))
170        {
171            /* already at bottom */
172        }
173        else
174        if (up <= -MAX_GUIDE_ENTRIES) 
175        {
176            /* jump one page down */
177            p_gs->offset += MAX_GUIDE_ENTRIES;
178            p_gs->selection += MAX_GUIDE_ENTRIES;
179            if (p_gs->offset >= p_app->settings.num_channels) 
180            {
181                BDBG_ERR(("p_gs->offset = %d >= %d\n", p_gs->offset,p_app->settings.num_channels));
182                p_gs->offset -= MAX_GUIDE_ENTRIES;
183            }
184
185            if (p_gs->selection >= p_app->settings.num_channels)
186            {
187                BDBG_ERR(("p_gs->selection = %d >= %d\n", p_gs->selection,p_app->settings.num_channels));
188                p_gs->selection = p_app->settings.num_channels - 1;
189            }
190                        /* update from top of guild entry of current page */
191                        p_app->chm.cur_ch_num = p_gs->offset;
192                        p_app->chm.epg_update_ch_num = p_gs->offset;
193                        if (p_app->chm.epg_update_ch_num > 0)
194                                p_app->chm.epg_update_ch_num--;
195            result = 1;
196        }
197        else
198        if (p_gs->selection < end_idx)
199        {
200            p_gs->selection++;
201            p_old_info = screen_guide_get_info(p_app,old_sel);
202            p_info = screen_guide_get_info(p_app,p_gs->selection);
203            //bapp_sync(p_app);
204            if (p_old_info)
205                draw_guide_entry(p_app,p_screen,p_gs, old_sel,p_old_info,false);
206                        if (p_info)
207                draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true);
208            bapp_flush_screen(p_app);
209            result = 1;
210        }
211        else 
212        if ((end_idx >= p_app->settings.num_channels) ||
213            (num_disp < MAX_GUIDE_ENTRIES)) 
214        {
215            /* do nothing */
216                        p_app->chm.epg_update_ch_num = p_app->chm.cur_ch_num;
217        }
218        else
219        {
220            p_gs->offset += MAX_GUIDE_ENTRIES;
221            p_gs->selection++;
222            if (p_gs->offset >= p_app->settings.num_channels)
223            {
224                BDBG_ERR(("p_gs->offset = %d >= %d\n", p_gs->offset,p_app->settings.num_channels));
225                p_gs->offset -= MAX_GUIDE_ENTRIES;
226                p_gs->selection = p_app->settings.num_channels - 1;
227            }
228                        /* update from top of guild entry of current page */
229                        p_app->chm.cur_ch_num = p_gs->offset;
230                        p_app->chm.epg_update_ch_num = p_gs->offset;
231                        if (p_app->chm.epg_update_ch_num > 0)
232                                p_app->chm.epg_update_ch_num--;
233            result = 1;
234        }
235    }
236    return result;
237}
238
239/*
240 * Summary:
241 *     Guide event handling. return 0 if no redrawing should be done.
242 */
243static void screen_guide_handle_redraw(bapp_t *p_app, bscreen_t *p_screen,guide_state_t *p_gs, int idx)
244{
245    chm_info_t *p_info;
246    int start_idx,end_idx;
247
248    start_idx = p_gs->offset;
249    end_idx = GUIDE_MIN((p_app->settings.num_channels - 1), 
250                (p_gs->offset + (MAX_GUIDE_ENTRIES - 1)));
251   
252    if ((idx < start_idx) || (idx > end_idx))
253    {
254        return;
255    }
256
257    p_info = screen_guide_get_info(p_app,idx);
258    /*bapp_sync(p_app);*/
259    if (p_info)
260        draw_guide_entry(p_app,p_screen,p_gs, idx,p_info,(idx == p_gs->selection) ? true : false);
261    bapp_flush_screen(p_app);
262}
263
264/*
265Summary:
266        Guide event handling
267        return result;
268        .
269*/
270int screen_guide_event(void *v_app, void *v_screen, bscreen_event_t *p_event)
271{
272        bapp_t *p_app = (bapp_t*)v_app;
273        bscreen_t *p_screen = (bscreen_t*)v_screen;
274        guide_state_t *p_gs;
275        int result = 0;
276
277        p_gs = (guide_state_t*)p_screen->local_state;
278        BDBG_ASSERT(p_gs);
279
280        switch (p_event->type)
281        {
282                case eS_EVENT_SETUP:
283                        {
284                                bscreen_default_setup(v_app,v_screen);
285                                p_gs->column = 1;
286
287                                if (p_app->chm.cur_epg_ch_num)
288                                {
289                                        p_gs->offset = (p_app->chm.cur_epg_ch_num /MAX_GUIDE_ENTRIES) * MAX_GUIDE_ENTRIES;
290                                        p_gs->selection = p_app->chm.cur_epg_ch_num;
291                                        /* we want to update from beginning in a page */
292                                        p_app->chm.epg_update_ch_num = p_gs->offset;
293                                }
294                                else
295                                {
296                                        p_gs->selection = 0;
297                                        p_gs->offset = 0;
298                                        p_app->chm.epg_update_ch_num = 0;
299                                }
300                                memset(&p_gs->event,0,sizeof(p_gs->event));
301                                p_gs->repeat_rate = 1;
302                                p_gs->repeat_timeout = DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate;
303                                result = 1; /* always handle event */
304                                /* if enter the guide screen, retune is needed when quiting from the UI */
305                                p_app->re_tune = true;
306                        }
307                        break;
308                case eS_EVENT_SETUP_DONE:
309                        {
310                                if (p_app->settings.num_channels == 0)
311                                {
312                                        /* set update progress to done since there are no channels */
313                                        p_gs->update_progress = 100;
314                                }
315                                else
316                                {
317                                        p_gs->update_progress = 0;
318                                }
319                                p_app->chm.last_freq_hz = 0;
320                                p_app->chm_cmd.cmd_id = eCHM_GUIDE;
321                                chm_cmd(&p_app->chm, &p_app->chm_cmd);
322                                bos_sleep(100); /* give time for command to be processed */
323                        }
324                        break;
325                case eS_EVENT_PROGRESS:
326                        {
327                                p_gs->update_progress = p_event->id;
328
329                                if (p_gs->update_progress <= 100)
330                                {
331                                        int num_chars = SCREEN_MAX_STR_WIDTH;
332                                        int w = 0;
333                                        int h = 0;
334
335                                        /* draw progress text */
336                                        bscreen_get_string(p_app->lang,eTEXT_GUIDE_DL_PROGRESS, p_app->tmp_str, &num_chars);
337                                        bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
338                                        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
339                                                ePROGRESS_GUIDE_X - w - 7, ePROGRESS_GUIDE_TEXT_Y - 4,
340                                                w + 3, ePROGRESS_GUIDE_TEXT_HEIGHT,  p_app->tmp_str,
341                                                num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,100);
342
343                                        bscreen_draw_progress(v_app, ePROGRESS_GUIDE_X, ePROGRESS_GUIDE_Y, ePROGRESS_GUIDE_WIDTH, ePROGRESS_GUIDE_HEIGHT, 
344                                                eBUTTON_VOL_PROGRESS_BORDER, eCOLOR_WHITE, eCOLOR_DRK_BLUE, p_gs->update_progress, 100);
345
346                                        /* update entry if with current display screen since redrew message was overwroten by progress message */
347                                        {
348                                                /* adjust channel index to previous one */
349                                                int idx = p_app->chm.cur_ch_num - 1;
350
351                                                if (idx < 0) {
352                                                        if (p_app->settings.num_channels > 1)
353                                                                idx = (p_app->settings.num_channels - 1);       
354                                                        else
355                                                                idx = 0;
356                                                }
357                                                screen_guide_handle_redraw(p_app,p_screen,p_gs, idx);
358                                        }
359                                }
360                                else
361                                {
362                                        //bgfx_fill_rect(&p_app->surf,ePROGRESS_GUIDE_TEXT_X,ePROGRESS_GUIDE_Y,
363                                        //              ePROGRESS_GUIDE_X+ePROGRESS_GUIDE_WIDTH-ePROGRESS_GUIDE_TEXT_X+3,ePROGRESS_GUIDE_HEIGHT+3,eCOLOR_LT_BLUE);
364                                }
365                                bapp_flush_screen(p_app);
366                        }
367                        break;
368                case eS_EVENT_REDRAW:
369                        {
370                                screen_guide_handle_redraw(p_app,p_screen,p_gs,p_event->id);
371                                /*bapp_new_screen(p_app);*/
372                        }
373                        break;
374                case eS_EVENT_IR:
375                        {
376                                switch (p_event->id)
377                                {
378                                        case eIR_SELECT:
379                                                if (p_gs->column == 1)
380                                                {
381                                                        if (p_app->settings.ch[p_gs->selection].skip) {
382                                                                /* skip channel, don't allow to quit? */
383                                                                result = 1;
384                                                                break;
385                                                        }
386                                                        p_app->cur_ch_num = p_gs->selection;
387                                                        bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]);
388                                                        bapp_set_current_screen(p_app,eSCREEN_BANNER_SMALL,eSCREEN_NULL);
389#ifdef CONFIG_CH_HIDDEN
390                                                        if (!p_app->settings.wiz_completed)
391                                                        {
392                                                                p_app->settings.wiz_completed = true;
393                                                                /* select exits to live tv so we must clear all the button selection history for all screens */
394                                                                bapp_clear_screen_selection_history(p_app);
395                                                        }
396#endif
397                                                        bapp_enable_cc(p_app, true);
398                                                        if (p_app->system_mute) 
399                                                                bapp_audio_do_mute(p_app, false);
400                                                        bapp_audio_mute(p_app, false);
401                                                }
402                                                else
403                                                {
404#ifdef CONFIG_CH_HIDDEN
405                                                        /* add/remove channel from ch+/- list */
406                                                        if (p_gs->selection < p_app->settings.num_channels)
407                                                                p_app->settings.ch[p_gs->selection].hidden = !p_app->settings.ch[p_gs->selection].hidden; 
408                                                        p_app->settings_dirty = 1;
409                                                        p_info = screen_guide_get_info(p_app,p_gs->selection);
410                                                        //bapp_sync(p_app);
411                                                        if (p_info)
412                                                                draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true);
413                                                        bapp_flush_screen(p_app);
414#endif
415                                                }
416                                                result = 1;
417                                                break;
418#ifdef CONFIG_CH_HIDDEN
419                                        case eIR_LEFT:
420                                                {
421                                                        if (p_gs->column != 0)
422                                                        {
423                                                                p_info = screen_guide_get_info(p_app,p_gs->selection);
424                                                                //bapp_sync(p_app);
425                                                                if (p_info)
426                                                                        draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,false);
427                                                                p_gs->column = 0;
428                                                                if (p_info)
429                                                                        draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true);
430                                                                bapp_flush_screen(p_app);
431                                                        }
432                                                }
433                                                break;
434                                        case eIR_RIGHT:
435                                                {
436                                                        if (p_gs->column != 1)
437                                                        {
438                                                                p_info = screen_guide_get_info(p_app,p_gs->selection);
439                                                                //bapp_sync(p_app);
440                                                                if (p_info)
441                                                                        draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,false);
442                                                                p_gs->column = 1;
443                                                                if (p_info)
444                                                                        draw_guide_entry(p_app,p_screen,p_gs, p_gs->selection,p_info,true);
445                                                                bapp_flush_screen(p_app);
446                                                        }
447                                                }
448                                                break;
449#endif
450                                        case eIR_MENU:
451                                                /* if entered using the EGP button directly, then need to retune */
452                                                if (eSCREEN_NULL == p_screen->last_screen_id) {
453                                                        /* quit directly, retune is needed */
454                                                        bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]);
455                            bapp_enable_cc(p_app, true);
456                            if (p_app->system_mute)
457                                bapp_audio_do_mute(p_app, false);
458                            bapp_audio_mute(p_app, false);
459                                                }
460                                                else {
461                                                        /* don't tune if go back to channel scan menu */
462                                                }
463                                                bapp_goto_last_screen(p_app);
464                                                result = 1;
465                                                break;
466                                        case eIR_GUIDE:
467                                                /* for any IR remote that has EPG button and quit directly, retune is needed */
468                                                bapp_set_channel(p_app, &p_app->settings.ch[p_app->cur_ch_num]);
469                                                bapp_goto_last_screen(p_app);
470                                                result = 1;
471                                                break;
472                                        case eIR_CH_UP:
473                                                result = screen_guide_move(p_app,p_screen,MAX_GUIDE_ENTRIES);
474                                                break;
475                                        case eIR_UP:
476                                                result = screen_guide_move(p_app,p_screen,1);
477                                                break;
478                                        case eIR_CH_DOWN:
479                                                result = screen_guide_move(p_app,p_screen,-MAX_GUIDE_ENTRIES);
480                                                break;
481                                        case eIR_DOWN:
482                                                result = screen_guide_move(p_app,p_screen,0);
483                                                break;
484                                                /* goto detailed EPG screen */
485                                        case eIR_0:
486                                                {
487                                                        /* set current EPG channel entry accordingly */
488                                                        p_app->chm.cur_epg_ch_num = p_gs->selection;
489                                                        bapp_set_current_screen(p_app, eSCREEN_DETAILED_GUIDE, eSCREEN_GUIDE);
490                                                        result = 1;
491                                                }
492                                                break;
493                                        default:
494                                                break;
495                                }
496                                p_gs->event = *p_event;
497                                p_gs->repeat_rate = 1;
498                                p_gs->repeat_timeout = bos_getticks() + (DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate);
499                        }
500                        break;
501                case eS_EVENT_IDLE:
502                        {
503                                if (p_gs->repeat_timeout < bos_getticks())
504                                {
505                                        /* Handle repeating when key is held down */
506                                        if (p_gs->event.type == eS_EVENT_IR)
507                                        {
508                                                switch (p_gs->event.id)
509                                                {
510                                                        case eIR_UP:
511                                                        case eIR_CH_UP:
512                                                                result = screen_guide_move(p_app,p_screen,1);
513                                                                break;
514                                                        case eIR_DOWN:
515                                                        case eIR_CH_DOWN:
516                                                                result = screen_guide_move(p_app,p_screen,0);
517                                                                break;
518                                                        default: break;
519                                                }
520                                        }
521
522                                        if (p_gs->repeat_rate < MAX_REPEAT_ACCEL)
523                                        {
524                                                p_gs->repeat_rate += REPEAT_INC;
525                                        }
526                                        p_gs->repeat_timeout = bos_getticks() + (DEFAULT_REPEAT_TIMEOUT/p_gs->repeat_rate);
527                                }
528
529                                if (!result)
530                                        result = bscreen_default_idle(v_app,v_screen);
531                        }
532                        break;
533                default:
534                        {
535                                result = bscreen_default_event(v_app,v_screen,p_event);
536                        }
537                        break;
538        }
539        return result;
540}
541
542/*
543Summary:
544Draw the guide entry
545 */
546
547static void draw_guide_entry(bapp_t *p_app, bscreen_t *p_screen, guide_state_t *p_gs,
548                int idx, chm_info_t *p_info, bool selected)
549{
550        int x,y,num_chars,w,h,str_y,l_idx;
551        int bkgnd_color = eCOLOR_MED_BLUE;
552        int offset = 4;
553        int guide_width;
554        l_idx = idx;
555
556        if (p_app->settings.num_channels == 0)
557                return;
558
559        /* alternate medium and lt blue background */
560        bkgnd_color = ((l_idx % 2) ? eCOLOR_MED_BLUE : eCOLOR_LT_BLUE);
561        bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+offset,eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * (l_idx % MAX_GUIDE_ENTRIES)),
562                        eSCREEN_ACTION_SAFE_WIDTH - (2*offset), eSCREEN_GUIDE_HEIGHT,bkgnd_color);
563
564        /* String for channel column */
565        num_chars = snprintf(p_gs->ch_num_str,24,"%d.%d", 
566                        p_app->settings.ch[idx].major,
567                        p_app->settings.ch[idx].minor);
568
569        num_chars = c_to_uni_str(p_gs->ch_num_str,p_app->tmp_str,num_chars);
570        bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
571                        (const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
572
573        /* draw channel number column */
574        if ( l_idx >= MAX_GUIDE_ENTRIES)
575                l_idx = (l_idx % MAX_GUIDE_ENTRIES);
576        x = eSCREEN_GUIDE_X;
577        y = eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * l_idx);
578
579        str_y = y + (eSCREEN_GUIDE_HEIGHT - h)/2;
580        guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
581                        x, str_y, eSCREEN_GUIDE_CH_WIDTH, eSCREEN_GUIDE_HEIGHT, 
582                        p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
583
584        /* String for channel short name column */
585#ifdef CONFIG_CH_HIDDEN
586        /* limit to 4 callsign chars to make room for add/remove checkbox*/
587        num_chars = utf16_to_uni_str(p_app->settings.ch[idx].ch_name,p_app->tmp_str,4);
588#else
589        num_chars = utf16_to_uni_str(p_app->settings.ch[idx].ch_name,p_app->tmp_str,MAX_CH_SHORT_NAME_CHARS);
590#endif
591
592        if (num_chars == 0)
593        {
594                num_chars = MAX_CH_SHORT_NAME_CHARS;
595                bscreen_get_string(p_app->lang,eTEXT_NA_GUIDE_CH, p_app->tmp_str, &num_chars);
596        }
597        /* draw channel short name column */
598        x = eSCREEN_GUIDE_CH_NAME_X - 6;
599        bgfx_fill_rect(&p_app->surf,x, y, eSCREEN_GUIDE_CALLSIGN_WIDTH,eSCREEN_GUIDE_HEIGHT,bkgnd_color);
600        guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
601                        x, str_y, eSCREEN_GUIDE_CALLSIGN_WIDTH + 6, eSCREEN_GUIDE_HEIGHT, 
602                        p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
603
604#ifdef CONFIG_CH_HIDDEN
605#ifdef CONFIG_CH_HIDDEN_CHECKBOX
606        /* add/remove channel checkbox */
607        {
608                uint16_t check_x = x + eSCREEN_GUIDE_CALLSIGN_WIDTH + eBUTTON_RADIO_BOX_MARGIN_X - 5;
609                uint16_t check_y = y + (eBUTTON_RADIO_BOX_WIDTH / 4);
610
611                if ((idx < p_app->settings.num_channels) && (!p_app->settings.ch[idx].hidden))
612                {
613                        /* draw BLACK outline */
614                        bgfx_fill_rect(&p_app->surf,check_x,check_y,
615                                        eBUTTON_RADIO_BOX_WIDTH,eBUTTON_RADIO_BOX_WIDTH,eCOLOR_BLACK);
616
617                        /* draw GREEN checkbox background */
618                        bgfx_fill_rect(&p_app->surf,check_x + eBUTTON_RADIO_BOX_BORDER,check_y + eBUTTON_RADIO_BOX_BORDER,
619                                        eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),
620                                        eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),eCOLOR_NEON_GREEN);
621                        /* draw dot in middle for colorblind users */
622                        bgfx_fill_rect(&p_app->surf,check_x + (eBUTTON_RADIO_BOX_WIDTH / 2) - (eBUTTON_RADIO_BOX_DOT_WIDTH / 2),
623                                        check_y + (eBUTTON_RADIO_BOX_WIDTH / 2) - (eBUTTON_RADIO_BOX_DOT_WIDTH / 2),
624                                        eBUTTON_RADIO_BOX_DOT_WIDTH, eBUTTON_RADIO_BOX_DOT_WIDTH, eCOLOR_BLACK);
625                } else
626                {
627                        /* draw BLACK outline */
628                        bgfx_fill_rect(&p_app->surf,check_x,check_y,
629                                        eBUTTON_RADIO_BOX_WIDTH,eBUTTON_RADIO_BOX_WIDTH,eCOLOR_BLACK);
630
631                        /* draw WHITE checkbox background */
632                        bgfx_fill_rect(&p_app->surf,check_x + eBUTTON_RADIO_BOX_BORDER,check_y + eBUTTON_RADIO_BOX_BORDER,
633                                        eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),
634                                        eBUTTON_RADIO_BOX_WIDTH - (2 * eBUTTON_RADIO_BOX_BORDER),eCOLOR_WHITE);
635                }
636        }
637#else
638        {
639                x += eSCREEN_GUIDE_CALLSIGN_WIDTH;
640                if ((idx < p_app->settings.num_channels) && (!p_app->settings.ch[idx].hidden))
641                {
642                        num_chars = SCREEN_MAX_STR_WIDTH;
643                        bscreen_get_string(p_app->lang,eTEXT_STORED, p_app->tmp_str, &num_chars);
644                } else
645                {
646                        num_chars = SCREEN_MAX_STR_WIDTH;
647                        bscreen_get_string(p_app->lang,eTEXT_SKIPPED, p_app->tmp_str, &num_chars);
648                }
649                bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
650                                (const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
651
652                if (selected && (p_gs->column == 0))
653                {
654                        bbutton_t button;
655                        button.text_id = eTEXT_MAX;
656                        button.desc_text_id = eTEXT_MAX;
657                        button.type = eBUTTON_MENU;
658                        button.x = x-offset;
659                        button.y = y;
660                        button.width = eSCREEN_GUIDE_HIDDEN_WIDTH[p_app->lang];
661                        button.height = eSCREEN_GUIDE_HEIGHT;
662
663                        bscreen_draw_button_str(p_app,&button,selected,0,p_app->tmp_str,
664                                        num_chars,NULL,0,eFONT_SIZE_SMALL,0);
665                }
666                else
667                {
668                        guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
669                                        x, str_y, eSCREEN_GUIDE_HIDDEN_WIDTH[p_app->lang], eSCREEN_GUIDE_HEIGHT, 
670                                        p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
671                }
672        }
673#endif
674#endif
675
676        /* String channel name column */
677        if (p_info)
678                num_chars = c_to_uni_str(p_info->eit_info[EIT_CURRENT].prog_title,p_app->tmp_str,MAX_TITLE_CHARS);
679        else
680                num_chars = 0;
681
682        if (num_chars == 0)
683        {
684                /*        num_chars = snprintf(p_gs->ch_num_str,31,"Channel - %d.%d", */
685                /*                 p_app->settings.ch[idx].major,*/
686                /*                 p_app->settings.ch[idx].minor);*/
687                /*        num_chars = c_to_uni_str(p_gs->ch_num_str,p_app->tmp_str,num_chars);*/
688
689                num_chars = SCREEN_MAX_STR_WIDTH;
690                bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars);
691        }
692        else {
693                if (num_chars > 18) {
694                        num_chars = 18;
695                }       
696        }
697        p_app->tmp_str[num_chars] = 0; 
698
699#ifdef CONFIG_CH_HIDDEN
700        x = eSCREEN_GUIDE_CUR_X[p_app->lang];
701        guide_width = eSCREEN_GUIDE_NAME_WIDTH[p_app->lang];
702#else
703        x = eSCREEN_GUIDE_CUR_X;
704        guide_width = eSCREEN_GUIDE_NAME_WIDTH;
705#endif
706
707        bgfx_fill_rect(&p_app->surf,x-1, y-1, guide_width + 2,eSCREEN_GUIDE_HEIGHT + 2,bkgnd_color);
708        if (selected && (p_gs->column == 1))
709        {
710                bbutton_t button;
711                button.text_id = eTEXT_MAX;
712                button.desc_text_id = eTEXT_MAX;
713                button.type = eBUTTON_MENU;
714                button.x = x-offset;
715                button.y = y;
716                button.width = guide_width+offset;
717                button.height = eSCREEN_GUIDE_HEIGHT;
718
719                bscreen_draw_button_str(p_app,&button,selected,0,p_app->tmp_str,
720                                num_chars,NULL,0,eFONT_SIZE_SMALL,0);
721        }
722        else
723        {
724                /* draw channel name column */
725                guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
726                                x, str_y, guide_width, eSCREEN_GUIDE_HEIGHT, 
727                                p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
728        }
729
730        /* String for current column */
731        if (p_info)
732                num_chars = c_to_uni_str(p_info->eit_info[EIT_NEXT].prog_title,p_app->tmp_str,MAX_TITLE_CHARS);
733        else
734                num_chars = 0;
735
736        if (num_chars == 0)
737        {
738                num_chars = SCREEN_MAX_STR_WIDTH;
739                bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars);
740        }
741        else {
742                /* changed from 16 to 17 to fix text in the middle issue */
743                if (num_chars > 17) {
744                        num_chars = 17;
745                }
746        }
747        p_app->tmp_str[num_chars] = 0; 
748
749        /* draw channel column */
750        x = eSCREEN_GUIDE_NEXT_X;
751        bgfx_fill_rect(&p_app->surf,x, y, guide_width,eSCREEN_GUIDE_HEIGHT,bkgnd_color);
752        guide_text_box(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
753                        x, str_y, guide_width, eSCREEN_GUIDE_HEIGHT, 
754                        p_app->tmp_str, num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
755}
756
757/*
758Summary:
759Get the guide info for this entry.
760 */
761static chm_info_t* screen_guide_get_info(bapp_t *p_app, int idx)
762{
763        if (idx < 0 || idx >= p_app->settings.num_channels)
764        {
765                return NULL;
766        }
767        return &(p_app->chm.p_info[idx]);
768}
769
770/*
771Summary:
772Guide screen drawing function
773 */
774void bscreen_guide_draw(void *v_app, void *v_screen)
775{
776        bapp_t *p_app = (bapp_t*)v_app;
777        bscreen_t *p_screen = (bscreen_t*)v_screen;
778        guide_state_t *p_gs;
779        unsigned int num_chars;
780        chm_info_t      *p_info;
781        int idx, w, h;
782
783        p_gs = (guide_state_t*)p_screen->local_state;
784        BDBG_ASSERT(p_gs);
785
786        bscreen_draw_background(v_app, &p_app->surf, p_screen->top_banner_height);
787
788        /* draw title */
789        num_chars = SCREEN_MAX_STR_WIDTH;
790        bscreen_get_string(p_app->lang,p_screen->title_text_id, p_app->tmp_str, &num_chars);
791        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_LARGE],
792                        eMENU_TITLE_TEXT_X, eMENU_TITLE_TEXT_Y,
793                        eMENU_TITLE_TEXT_WIDTH, eMENU_TITLE_TEXT_HEIGHT,  p_app->tmp_str,
794                        num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
795
796        /* draw progress text */
797        num_chars = SCREEN_MAX_STR_WIDTH;
798        bscreen_get_string(p_app->lang,eTEXT_GUIDE_DL_PROGRESS, p_app->tmp_str, &num_chars);
799        bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
800        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
801                        ePROGRESS_GUIDE_X - w - 7, ePROGRESS_GUIDE_TEXT_Y - 4,
802                        w + 3, ePROGRESS_GUIDE_TEXT_HEIGHT,  p_app->tmp_str,
803                        num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,100);
804
805        bscreen_draw_progress(v_app, ePROGRESS_GUIDE_X, ePROGRESS_GUIDE_Y, ePROGRESS_GUIDE_WIDTH, ePROGRESS_GUIDE_HEIGHT, 
806                        eBUTTON_VOL_PROGRESS_BORDER, eCOLOR_WHITE, eCOLOR_DRK_BLUE, p_gs->update_progress, 100);
807
808        /* draw column header bar */
809        bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+4,
810                        eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22,
811                        eSCREEN_ACTION_SAFE_WIDTH-8,eINFO_AREA_HEIGHT - 6,eCOLOR_DRK_BLUE);
812
813        /* draw column header */
814        num_chars = SCREEN_MAX_STR_WIDTH;
815        bscreen_get_string(p_app->lang,eTEXT_GUIDE_HEADER, p_app->tmp_str, &num_chars);
816        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
817                        eSCREEN_GUIDE_X, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16,
818                        eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str,
819                        num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
820
821        if (p_app->settings.num_channels > 0)
822        {
823                /* Draw the guide entries */
824                for (idx = p_gs->offset; idx < GUIDE_MIN(p_app->settings.num_channels,
825                                        (p_gs->offset + MAX_GUIDE_ENTRIES)); ++idx)
826                {
827                        p_info = screen_guide_get_info(p_app,idx);
828                        if (p_info) {
829                                draw_guide_entry(p_app,p_screen,p_gs, idx,p_info, (idx == p_gs->selection) ? true : false);
830                        }
831                }
832        }
833        else
834        {
835                int w = 0;
836                int h = 0;
837                /* No channels in channel map so show "No Programs Available" */
838                num_chars = SCREEN_MAX_STR_WIDTH;
839                bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars);
840                bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],(const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
841                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
842                                eSCREEN_GUIDE_X+((eWIDTH-(2*eSCREEN_GUIDE_X))/2)-(w/2), 
843                                eSCREEN_ACTION_SAFE_Y + eSCREEN_ACTION_SAFE_HEIGHT/2,
844                                w+5, h, p_app->tmp_str,
845                                num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
846        }
847
848        draw_navigation_hints(v_app, v_screen);
849}
850
851/*
852Summary:
853Change to next channel's EPG
854 */
855int screen_detailed_guide_move_channel(bapp_t *p_app, bscreen_t *p_screen, int up)
856{
857        /* check to make sure there are at least 2 channels to move channel up or down */
858        if (p_app->settings.num_channels < 2)
859                return 1;
860
861        /* if moving channel up */
862        if (up > 0)
863        {
864                p_app->chm.cur_epg_ch_num--;
865                if (p_app->chm.cur_epg_ch_num < 0)
866                        p_app->chm.cur_epg_ch_num = p_app->settings.num_channels - 1;
867        }
868        else {
869                p_app->chm.cur_epg_ch_num++;
870        }
871        /* remember it so that when go back to GUIDE screen, the current viewed EPG entry will be reflected accordingly */
872        p_app->chm.cur_epg_ch_num %= p_app->settings.num_channels;
873
874        bscreen_detailed_guide_draw((void *)p_app, (void *)p_screen);
875        return 1;
876}
877
878/*
879Summary:
880Detail Guide handling. return 0 if no redrawing should be done.
881 */
882int screen_detailed_guide_move(bapp_t *p_app, bscreen_t *p_screen, int up)
883{
884        int start_idx,end_idx,num_disp,result =0;
885        guide_state_t *p_gs;
886        p_gs = (guide_state_t*)p_screen->local_state;
887        BDBG_ASSERT(p_gs);
888
889        start_idx = p_gs->offset;
890        end_idx = GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + (MAX_GUIDE_ENTRIES - 1)));
891        num_disp = (end_idx - start_idx + 1);
892
893        /* If moving selection up */
894        if (up > 0)
895        {
896                if (p_gs->selection == 0)
897                {
898                        /* already at top */
899                }
900                else 
901                {
902                        /* jump one page up */
903                        start_idx -= MAX_GUIDE_ENTRIES;
904                        p_gs->selection -= MAX_GUIDE_ENTRIES;
905                        if (start_idx < 0)
906                        {
907                                start_idx = 0;
908                                p_gs->selection = 0;
909                        }
910                        p_gs->offset = start_idx;
911                        result = 1;
912                }
913        }
914        else /* moving selection down */
915        {
916                if (p_gs->selection >= (MAX_EIT_NUM - 1))
917                {
918                        /* already at bottom */
919                }
920                else
921                {
922                        /* jump one page down */
923                        p_gs->offset += MAX_GUIDE_ENTRIES;
924                        p_gs->selection += MAX_GUIDE_ENTRIES;
925                        if (p_gs->offset >= MAX_EIT_NUM) 
926                        {
927                                p_gs->offset -= MAX_GUIDE_ENTRIES;
928                                p_gs->selection = MAX_EIT_NUM - 1;
929                        }
930                        result = 1;
931                }
932        }
933        return result;
934}
935
936#if 0
937/*
938 * Summary:
939 *      Detailed Guide draw function.
940 */
941static void screen_detailed_guide_handle_redraw(bapp_t *p_app, bscreen_t *p_screen,detailed_guide_state_t *p_gs, int idx)
942{
943        chm_info_t *p_info;
944        int start_idx,end_idx;
945
946        start_idx = p_gs->offset;
947        end_idx = GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + (MAX_GUIDE_ENTRIES - 1)));
948
949        if ((idx < start_idx) || (idx > end_idx))
950        {
951                /* not in the page */
952                return;
953        }
954
955        p_info = screen_guide_get_info(p_app,idx);
956        if (p_info) {
957                draw_detailed_guide_entry(p_app,p_screen,p_gs, idx,p_info,(0 == idx) ? true : false);
958                bapp_flush_screen(p_app);
959        }
960}
961#endif
962
963/*
964Summary:
965Detailed Guide event handling
966return result;
967 */
968int screen_detailed_guide_event(void *v_app, void *v_screen, bscreen_event_t *p_event)
969{
970        bapp_t *p_app = (bapp_t*)v_app;
971        bscreen_t *p_screen = (bscreen_t*)v_screen;
972        detailed_guide_state_t *p_gs;
973        int result = 0;
974        bapp_ch_t *pch;
975
976        p_gs = (detailed_guide_state_t*)p_screen->local_state;
977        BDBG_ASSERT(p_gs);
978
979        switch (p_event->type)
980        {
981                case eS_EVENT_SETUP:
982                        {
983                                bscreen_default_setup(v_app,v_screen);
984
985                                /* always start from current EPG time which is the first entry in EIT array */
986                                p_gs->selection = 0;
987                                p_gs->offset = 0;
988                                /* note that the p_gs->ch_num has been set in the guide_event */
989                                result = 1; /* always handle event */
990                                /* remember current settings in case need to save them */
991                                pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num];
992                                p_gs->skip = pch->skip;
993                                p_gs->favorite = pch->favorite;
994                                p_gs->save = false;
995                        }
996                        break;
997                case eS_EVENT_REDRAW:
998                        {
999                                //screen_detailed_guide_handle_redraw(p_app,p_screen,p_gs, p_gs->offset);
1000                                result = 1;
1001                        }
1002                        break;
1003                case eS_EVENT_IR:
1004                        {
1005                                switch (p_event->id)
1006                                {
1007                                        case eIR_MENU:
1008                                        case eIR_GUIDE:
1009                                                bapp_goto_last_screen(p_app);
1010                                                pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num];
1011                                                if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) {
1012                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip;
1013                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite;
1014                                                        p_gs->save = true;
1015                                                }
1016                                                if (p_gs->save)
1017                                                        p_app->settings_dirty |= DIRTY_CHANNEL_MAP;
1018                                                result = 1;
1019                                                break;
1020                                        case eIR_UP:
1021                                                result = screen_detailed_guide_move(p_app,p_screen,true);
1022                                                break;
1023                                        case eIR_DOWN:
1024                                                result = screen_detailed_guide_move(p_app,p_screen,false);
1025                                                break;
1026                                        case eIR_CH_DOWN:
1027                                                pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num];
1028                        if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) {
1029                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip;
1030                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite;
1031                                                        p_gs->save = true;
1032                        }
1033                                                result = screen_detailed_guide_move_channel(p_app, p_screen, true);
1034                                                /* remember current settings in case need to save them */
1035                                                pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num];
1036                                                p_gs->skip = pch->skip;
1037                                p_gs->favorite = pch->favorite;
1038                                                break;
1039                                        case eIR_CH_UP:
1040                        if (p_gs->skip != pch->skip || p_gs->favorite != pch->favorite) {
1041                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].skip = p_gs->skip;
1042                                                        p_app->settings.ch[p_app->chm.cur_epg_ch_num].favorite = p_gs->favorite;
1043                                                        p_gs->save = true;
1044                        }
1045                                                result = screen_detailed_guide_move_channel(p_app, p_screen, false);
1046                                                /* remember current settings in case need to save them */
1047                                                pch = &p_app->settings.ch[p_app->chm.cur_epg_ch_num];
1048                                                p_gs->skip = pch->skip;
1049                                                p_gs->favorite = pch->favorite;
1050                                                break;
1051                                        case eIR_0:
1052                                                /* toggle skip */
1053                                                p_gs->skip = !p_gs->skip;
1054                                                bscreen_detailed_guide_options_draw(v_app, v_screen);
1055                                bapp_flush_screen(p_app);
1056                                                break;
1057                                        case eIR_8:
1058                                                /* toggle favorite */
1059                                                p_gs->favorite = !p_gs->favorite;
1060                                                bscreen_detailed_guide_options_draw(v_app, v_screen);
1061                                bapp_flush_screen(p_app);
1062                                                break;
1063                                        default:
1064                                                break;
1065                                }
1066                        }
1067                        break;
1068                case eS_EVENT_IDLE:
1069                        {
1070                                result = bscreen_default_idle(v_app,v_screen);
1071                        }
1072                        break;
1073                default:
1074                        {
1075                                result = bscreen_default_event(v_app,v_screen,p_event);
1076                        }
1077                        break;
1078        }
1079        return result;
1080}
1081
1082/*
1083Summary:
1084Draw detailed guide entry
1085 */
1086static 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)
1087{
1088        int x,y,num_chars,l_idx = idx;
1089        int bkgnd_color;
1090        int offset = 4;
1091        bool dst;
1092        unsigned utc_time;
1093        b_tm s_tm;
1094
1095        if (p_app->settings.num_channels == 0) {
1096                /* no channel, shouldn't be called in the first place */
1097                return;
1098        }
1099
1100        if (idx >= MAX_EIT_NUM) {
1101                /* out of range? */
1102                return;
1103        }
1104
1105        /* alternate medium and light blue background */
1106        bkgnd_color = ((l_idx % 2) ? eCOLOR_MED_BLUE : eCOLOR_LT_BLUE);
1107        bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+offset,eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * (l_idx % MAX_GUIDE_ENTRIES)),
1108                        eSCREEN_ACTION_SAFE_WIDTH - (2*offset), eSCREEN_GUIDE_HEIGHT,bkgnd_color);
1109
1110        if (l_idx >= MAX_GUIDE_ENTRIES)
1111                l_idx = (l_idx % MAX_GUIDE_ENTRIES);
1112
1113        x = eSCREEN_GUIDE_X;
1114        y = eSCREEN_GUIDE_Y_OFF + (eSCREEN_GUIDE_HEIGHT * l_idx);
1115
1116        if (0 == p_info->eit_info[EIT_CURRENT].start_time || 0 == p_info->eit_info[EIT_CURRENT].length) {
1117                /* just show no data in first entry */
1118                if (selected) {
1119                        num_chars = SCREEN_MAX_STR_WIDTH;
1120                        bscreen_get_string(p_app->lang,eTEXT_NO_GUIDE_DATA, p_app->tmp_str, &num_chars);
1121                        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1122                                        x, y, eBANNER_START_END_TIME_WIDTH, eBANNER_START_END_TIME_HEIGHT,
1123                                        p_app->tmp_str, num_chars, selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0);
1124                }
1125                return;
1126        }
1127
1128        /* draw time range column */
1129        num_chars = MAX_TIME_STR;
1130        if (chm_get_time_info(&p_app->chm,&utc_time,&offset,&dst) == 0)
1131        {
1132                utc_time += offset;
1133                utctime(utc_time,&s_tm);
1134
1135                /* draw program start/end time if exists */
1136                if ((p_info->eit_info[idx].start_time > 0) &&
1137                                (p_info->eit_info[idx].length > 0))
1138                {
1139                        unsigned char prog_time_str[MAX_TIME_STR * 2];
1140                        unsigned char prog_start_time_str[MAX_TIME_STR];
1141                        unsigned char prog_end_time_str[MAX_TIME_STR];
1142                        b_tm tm_start;
1143                        b_tm tm_end;
1144
1145                        if (dst)
1146                        {
1147                                offset += 3600; /* utc_time is already offset for dst but offset is not */
1148                        }
1149
1150                        utctime(p_info->eit_info[idx].start_time + offset, &tm_start);
1151                        if (tm_start.tm_hour >= 12)
1152                        {
1153                                if (tm_start.tm_hour > 12)
1154                                        tm_start.tm_hour -= 12;
1155                                snprintf(prog_start_time_str,MAX_TIME_STR,"%02d:%02dPM",tm_start.tm_hour,tm_start.tm_min);
1156                        } else {
1157                                if (tm_start.tm_hour == 0)
1158                                        tm_start.tm_hour = 12;
1159                                snprintf(prog_start_time_str,MAX_TIME_STR,"%02d:%02dAM",tm_start.tm_hour,tm_start.tm_min);
1160                        }
1161
1162                        utctime(p_info->eit_info[idx].start_time + p_info->eit_info[idx].length + offset, &tm_end);
1163                        if (tm_end.tm_hour >= 12)
1164                        {
1165                                if (tm_end.tm_hour > 12)
1166                                        tm_end.tm_hour -= 12;
1167                                snprintf(prog_end_time_str,MAX_TIME_STR,"%02d:%02dPM",tm_end.tm_hour,tm_end.tm_min);
1168                        } else {
1169                                if (tm_end.tm_hour == 0)
1170                                        tm_end.tm_hour = 12;
1171                                snprintf(prog_end_time_str,MAX_TIME_STR,"%02d:%02dAM",tm_end.tm_hour,tm_end.tm_min);
1172                        }
1173                        snprintf(prog_time_str, (MAX_TIME_STR * 2), "%s-%s",prog_start_time_str,prog_end_time_str);
1174                        num_chars = MAX_TIME_STR * 2;
1175                        num_chars = c_to_uni_str(prog_time_str,p_app->tmp_str,num_chars);
1176
1177                        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1178                                        x, y, eBANNER_START_END_TIME_WIDTH, eBANNER_START_END_TIME_HEIGHT, 
1179                                        p_app->tmp_str, num_chars, selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0);
1180
1181                        /* draw program title */
1182                        num_chars = c_to_uni_str(p_info->eit_info[idx].prog_title,p_app->tmp_str,MAX_TITLE_CHARS);
1183                        if (num_chars > 0)
1184                        {
1185                                if (num_chars > 40)
1186                                        num_chars = 30;
1187                                x = eSCREEN_DETAILED_GUIDE_X;
1188                                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1189                                                x, y, eSCREEN_DETAILED_GUIDE_WIDTH, eBANNER_TITLE_HEIGHT, p_app->tmp_str, num_chars, 
1190                                                (selected ? eCOLOR_MED_YELLOW : eCOLOR_WHITE),eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,0);
1191                        }
1192                }
1193        }
1194}
1195
1196/*
1197Summary:
1198        Channel Info (skip/fav) drawing function
1199 */
1200void bscreen_detailed_guide_options_draw(void *v_app, void *v_screen)
1201{
1202        bapp_t *p_app = (bapp_t*)v_app;
1203        bscreen_t *p_screen = (bscreen_t*)v_screen;
1204        detailed_guide_state_t *p_gs;
1205        unsigned int num_chars;
1206        int w,h,x;
1207        char ch_num_str[24];
1208
1209        p_gs = (detailed_guide_state_t*)p_screen->local_state;
1210        BDBG_ASSERT(p_gs);
1211
1212        x = 250;
1213        /* clear previous one */
1214        bgfx_fill_rect(&p_app->surf,x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22,
1215                eSCREEN_ACTION_SAFE_WIDTH - 8 -x, 20, eCOLOR_DRK_BLUE);
1216
1217        /* English translation is same as Spanish, so hardcoding it */
1218        num_chars = snprintf(ch_num_str,24,"%s", "Skip");
1219        num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars);
1220        if (p_gs->skip) {
1221                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1222                        x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 17, 60, eINFO_AREA_HEIGHT, p_app->tmp_str,
1223                        num_chars, eCOLOR_RED,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW, 0);
1224        }
1225        if (p_gs->favorite) {
1226                bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
1227                x += (w + 10);
1228                /* English translation is same as Spanish, so hardcoding it */
1229                num_chars = snprintf(ch_num_str,24,"%s", "Fav");
1230                num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars);
1231                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1232                        x, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 17, w + 6, eINFO_AREA_HEIGHT, p_app->tmp_str,
1233                        num_chars, eCOLOR_RED,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW, 0);
1234        }
1235}
1236
1237/*
1238Summary:
1239Guide screen drawing function
1240 */
1241void bscreen_detailed_guide_draw(void *v_app, void *v_screen)
1242{
1243        bapp_t *p_app = (bapp_t*)v_app;
1244        bscreen_t *p_screen = (bscreen_t*)v_screen;
1245        detailed_guide_state_t *p_gs;
1246        unsigned int num_chars;
1247        chm_info_t      *p_info;
1248        int i,w,h;
1249        char ch_num_str[24];
1250
1251        p_gs = (detailed_guide_state_t*)p_screen->local_state;
1252        BDBG_ASSERT(p_gs);
1253
1254        bscreen_draw_background(v_app, &p_app->surf, p_screen->top_banner_height);
1255
1256        /* draw title */
1257        num_chars = SCREEN_MAX_STR_WIDTH;
1258        bscreen_get_string(p_app->lang,p_screen->title_text_id, p_app->tmp_str, &num_chars);
1259        text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_LARGE],
1260                        eMENU_TITLE_TEXT_X, eMENU_TITLE_TEXT_Y, eMENU_TITLE_TEXT_WIDTH, eMENU_TITLE_TEXT_HEIGHT,  p_app->tmp_str,
1261                        num_chars, eCOLOR_MED_YELLOW,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
1262
1263        /* draw background */
1264        bgfx_fill_rect(&p_app->surf,eSCREEN_ACTION_SAFE_X+4, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 22,
1265                        eSCREEN_ACTION_SAFE_WIDTH-8,eINFO_AREA_HEIGHT - 6,eCOLOR_DRK_BLUE);
1266
1267        /* draw channel name */
1268        i = p_app->chm.cur_epg_ch_num;
1269        p_info = screen_guide_get_info(p_app, i);
1270        if (p_info) {
1271                /* draw channel number */
1272                num_chars = snprintf(ch_num_str,24,"%d.%d", p_app->settings.ch[i].major, p_app->settings.ch[i].minor);
1273                num_chars = c_to_uni_str(ch_num_str,p_app->tmp_str,num_chars);
1274
1275                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1276                                eSCREEN_GUIDE_X, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16, eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str,
1277                                num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
1278                /* find x location to draw channel name */
1279                bgfx_string_info(p_app->p_font[p_app->lang][eFONT_SIZE_SMALL], (const unsigned long *)p_app->tmp_str,num_chars,&w,&h);
1280
1281                num_chars = MAX_CH_NAME_CHARS+1;
1282                num_chars = utf16_to_uni_str(p_app->settings.ch[i].ch_name,p_app->tmp_str,num_chars);
1283
1284                text_box_shadow(&p_app->surf, p_app->p_font[p_app->lang][eFONT_SIZE_SMALL],
1285                                eSCREEN_GUIDE_X + w + 5, eMENU_TITLE_TEXT_Y + eMENU_TITLE_TEXT_HEIGHT + 16, eWIDTH, eINFO_AREA_HEIGHT, p_app->tmp_str,
1286                                num_chars, eCOLOR_WHITE,eCOLOR_BLACK, eMENU_TEXT_DROPSHADOW ,eSCREEN_GUIDE_SPACING);
1287
1288                /* draw skip and favorite */
1289                bscreen_detailed_guide_options_draw(v_app, v_screen);
1290
1291                /* Draw detailed guide entries for given channel */
1292                for (i = p_gs->offset; i < GUIDE_MIN(MAX_EIT_NUM, (p_gs->offset + MAX_GUIDE_ENTRIES)); i++)
1293                {
1294                        draw_detailed_guide_entry(p_app,p_screen,p_gs,i, p_info, (0 == i) ? true : false);
1295                }
1296        }
1297        else {
1298                /* should we draw no data */
1299        }
1300        draw_navigation_hints(v_app, v_screen);
1301}
1302
Note: See TracBrowser for help on using the repository browser.