source: trunk/core/gui.c @ 2791

Revision 2785, 112.5 KB checked in by philmoz, 40 hours ago (diff)

Enable 'RAW Develop' command to work with DNG files.
Remove DNG_SUPPORT #define - DNG module is always enabled.

  • Property svn:eol-style set to native
Line 
1#include "platform.h"
2#include "touchscreen.h"
3#include "conf.h"
4#include "font.h"
5#include "lang.h"
6#include "fileutil.h"
7#include "gui.h"
8#include "gui_lang.h"
9#include "gui_draw.h"
10#include "gui_menu.h"
11#include "gui_user_menu.h"
12#include "gui_mbox.h"
13#include "gui_hexbox.h"
14#include "gui_osd.h"
15#include "console.h"
16#include "raw.h"
17#include "modules.h"
18#include "levent.h"
19#ifdef CAM_HAS_GPS
20#include "gps.h"
21#endif
22#include "usb_remote.h"
23#include "module_load.h"
24
25//-------------------------------------------------------------------
26
27#define SPLASH_TIME               20
28
29//-------------------------------------------------------------------
30// forward declarations
31extern void schedule_memdump();
32
33//-------------------------------------------------------------------
34
35// for memory info, duplicated from lowlevel
36extern const char _start,_end;
37
38#ifdef OPT_DEBUGGING
39#ifndef CAM_DRYOS
40    int debug_tasklist_start;
41#endif
42    int debug_display_direction=1;
43#endif
44
45//-------------------------------------------------------------------
46
47int gui_user_menu_flag;
48
49static char buf[256];
50
51//-------------------------------------------------------------------
52// Menu definitions
53//-------------------------------------------------------------------
54
55//-------------------------------------------------------------------
56
57/*
58common code for "enum" menu items that just take a list of string values and don't require any special setters
59would be better to have another menu item type that does this by default
60save memory by eliminating dupe code
61*/
62void gui_enum_value_change(int *value, int change, unsigned num_items) {
63    *value+=change;
64    if (*value<0)
65        *value = num_items-1;
66    else if (*value>=num_items)
67        *value = 0;
68}
69
70static const char* gui_change_simple_enum(int* value, int change, const char** items, unsigned num_items) {
71    gui_enum_value_change(value, change, num_items);
72    return items[*value];
73}
74
75const char* gui_change_enum2(const CMenuItem *menu_item, int change)
76{
77    const char** items = (const char**)menu_item->arg;
78    gui_enum_value_change(menu_item->value, change, menu_item->opt_len);
79    return items[*menu_item->value];
80}
81
82//-------------------------------------------------------------------
83
84static const char* gui_bracket_values_modes[] = { "Off", "1/3 Ev","2/3 Ev", "1 Ev", "1 1/3Ev", "1 2/3Ev", "2 Ev", "2 1/3Ev", "2 2/3Ev", "3 Ev", "3 1/3Ev", "3 2/3Ev", "4 Ev" };
85static const char* gui_bracket_type_modes[] =   { "+/-", "-", "+", "-/+" };
86
87#if CAM_CAN_SD_OVERRIDE
88static CMenuItem sd_bracket[2] = {
89    MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.subj_dist_bracket_value,  MENU_MINMAX(0, 30000) ),
90    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.subj_dist_bracket_koef,   0 ),
91};
92#endif
93
94static CMenuItem iso_bracket[2] = {
95    MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_bracket_value,        MENU_MINMAX(0, 10000) ),
96    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.iso_bracket_koef,         0 ),
97};
98
99static CMenuItem bracketing_in_continuous_submenu_items[] = {
100    MENU_ENUM2  (0x63,LANG_MENU_TV_BRACKET_VALUE,           &conf.tv_bracket_value,         gui_bracket_values_modes ),
101#if CAM_HAS_IRIS_DIAPHRAGM
102    MENU_ENUM2  (0x62,LANG_MENU_AV_BRACKET_VALUE,           &conf.av_bracket_value,         gui_bracket_values_modes ),
103#endif
104#if CAM_CAN_SD_OVERRIDE
105    MENU_ITEM   (0x5e,LANG_MENU_SUBJ_DIST_BRACKET_VALUE,    MENUITEM_STATE_VAL_PAIR,        &sd_bracket,                        100 ),
106#endif
107    MENU_ITEM   (0x74,LANG_MENU_ISO_BRACKET_VALUE,          MENUITEM_STATE_VAL_PAIR,        &iso_bracket,                       10 ),
108    MENU_ENUM2  (0x60,LANG_MENU_BRACKET_TYPE,               &conf.bracket_type,             gui_bracket_type_modes ),
109    MENU_ITEM   (0x5b,LANG_MENU_CLEAR_BRACKET_VALUES,       MENUITEM_BOOL,                  &conf.clear_bracket,                0 ),
110    MENU_ITEM   (0x5c,LANG_MENU_BRACKETING_ADD_RAW_SUFFIX,  MENUITEM_BOOL,                  &conf.bracketing_add_raw_suffix,    0 ),
111    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
112    {0}
113};
114static CMenu bracketing_in_continuous_submenu = {0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS_TITLE, NULL, bracketing_in_continuous_submenu_items };
115
116//-------------------------------------------------------------------
117
118const char* gui_USB_switch_types[] = { "None","OnePush", "TwoPush", "CA-1" };                                                           // note : make sure # of entries less than NUM_USB_INPUT_DRV in usb_remote.c
119const char* gui_USB_control_modes[] = { "None", "Normal", "Quick", "Burst", "Bracket","Zoom", "Video" };        // note : make sure # of entries less than NUM_USB_MODULES in usb_remote.c
120
121static CMenuItem remote_submenu_items[] = {
122    MENU_ITEM   (0x71,LANG_MENU_REMOTE_ENABLE,              MENUITEM_BOOL,                  &conf.remote_enable, 0),
123    MENU_ENUM2  (0x5f,LANG_MENU_REMOTE_DEVICE,                  &conf.remote_switch_type,       gui_USB_switch_types ),
124    MENU_ENUM2  (0x5f,LANG_MENU_REMOTE_LOGIC,               &conf.remote_control_mode,      gui_USB_control_modes ),   
125    MENU_ITEM   (0x0, LANG_MENU_REMOTE_OPTIONS,             MENUITEM_SEPARATOR,             0, 0 ),
126        MENU_ITEM   (0x5c,LANG_MENU_SYNCH_ENABLE,               MENUITEM_BOOL,                  &conf.synch_enable, 0),
127    MENU_ITEM   (0x5c,LANG_MENU_SYNCH_DELAY_ENABLE,         MENUITEM_BOOL,                  &conf.synch_delay_enable, 0),
128    MENU_ITEM   (0x5e,LANG_MENU_SYNCH_DELAY_VALUE,          MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_value, 0),
129        MENU_ITEM   (0x5c,LANG_MENU_SCRIPT_START_ENABLE,        MENUITEM_BOOL,                  &conf.remote_enable_scripts, 0),
130        MENU_ITEM   (0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,          MENUITEM_SUBMENU,               &bracketing_in_continuous_submenu, 0 ),   
131//  MENU_ITEM   (0x5e,LANG_MENU_SYNCH_DELAY_COARSE_VALUE,   MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_coarse_value, 0),
132//  MENU_ITEM   (0x5e,LANG_MENU_REMOTE_ZOOM_TIMEOUT,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.zoom_timeout, MENU_MINMAX(2,10)),
133    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0, 0),
134    {0}
135};
136static CMenu remote_submenu = {0x86,LANG_MENU_REMOTE_PARAM_TITLE, NULL, remote_submenu_items };
137
138//-------------------------------------------------------------------
139
140static const char* gui_autoiso_shutter_modes[] =            { "Auto", "1/8s", "1/15s", "1/30s", "1/60s", "1/125s", "1/250s", "1/500s", "1/1000s" };
141static const int shutter1_values[]={0, 8, 15, 30, 60, 125, 250, 500, 1000 };
142
143static const char* gui_autoiso2_shutter_modes[]={ "Off", "1/4s", "1/6s", "1/8s", "1/12s", "1/15s", "1/20s", "1/25s", "1/30s", 
144                                         "1/40s", "1/50s", "1/60s", "1/80s", "1/100s", "1/125s", "1/160s", "1/250s", "1/500s", "1/1000s"};
145static const int shutter2_values[]={0, 4, 6, 8, 12, 15, 20, 25, 30, 40, 50, 60, 80, 100, 125, 160, 200, 250, 500, 1000 };
146
147static const char* gui_overexp_ev_modes[]={ "Off", "-1/3 Ev", "-2/3 Ev", "-1 Ev", "-1 1/3Ev", "-1 2/3Ev", "-2 Ev" };
148
149void cb_autoiso_menu_change(unsigned int item)
150{
151    conf.autoiso_min_shutter_numerator = shutter1_values[conf.autoiso_shutter_enum];
152    conf.autoiso2_min_shutter_numerator =  shutter2_values[conf.autoiso2_shutter_enum];
153
154    conf.autoiso_max_iso_auto_real=0;   // set invalid value of real autoiso as flag 'need recalc'
155}
156
157static CMenuItem autoiso_submenu_items[] = {
158    MENU_ITEM   (0x5c,LANG_MENU_AUTOISO_ENABLED,            MENUITEM_BOOL,                                      &conf.autoiso_enable,       0 ),
159    MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER,            &conf.autoiso_shutter_enum,                         gui_autoiso_shutter_modes ),
160    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_USER_FACTOR,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_user_factor,      MENU_MINMAX(1, 8) ),
161
162#if CAM_HAS_IS
163    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_IS_FACTOR,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_is_factor,        MENU_MINMAX(1, 8) ),
164#endif
165
166    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MIN_ISO,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_min_iso,          MENU_MINMAX(1, 20) ),
167    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MAX_ISO_AUTO,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_auto,         MENU_MINMAX(10, 320) ),
168
169    MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER2,       &conf.autoiso2_shutter_enum,                        gui_autoiso2_shutter_modes ),
170    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MAX_ISO2,                       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso2_max_iso_auto,        MENU_MINMAX(10, 320) ),
171
172#if CAM_HAS_HI_ISO_AUTO_MODE
173    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MAX_ISO_HI,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_hi,               MENU_MINMAX(20, 320) ),
174#endif
175
176    MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_OVEREXP_EV,             &conf.overexp_ev_enum, gui_overexp_ev_modes ),
177    MENU_ITEM   (0x57,LANG_MENU_ZEBRA_OVER,                     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso2_over,                MENU_MINMAX(0, 32) ),
178    MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_OVEREXP_THRES,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.overexp_threshold,            MENU_MINMAX(1, 20) ),
179
180    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,    0,                                                              0 ),
181    {0}
182};
183
184static CMenu autoiso_submenu = {0x2d,LANG_MENU_AUTOISO_TITLE, cb_autoiso_menu_change, autoiso_submenu_items };
185
186//-------------------------------------------------------------------
187
188#ifdef OPT_DEBUGGING
189
190static void gui_compare_props(int arg)
191{
192        #define NUM_PROPS 512
193        // never freed, but not allocated unless prop compare is used once
194        static int *props = NULL;
195        char buf[64];
196        int i;
197        int p;
198        int c;
199
200        if( props )
201        { // we have previous data set! do a comparison
202                c = 0;
203                for( i = 0; i < NUM_PROPS; ++i )
204                {
205                        p = shooting_get_prop(i);
206                        if( props[i] != p )
207                        {
208                                ++c;
209                                sprintf(buf,"%4d is %8d was %8d",i,p,props[i]);
210                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
211                        }
212                        props[i] = p;
213                        if( c == 12 )
214                        {
215                                ++c;
216                                sprintf(buf,"%s","Waiting 15 Seconds");
217                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
218                                msleep(15000);
219                                c = 0;
220                        }
221                }
222                ++c;
223                sprintf(buf,"%s","Press <ALT> to leave");
224                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
225        }
226        else
227        {
228        // no previous data was set so we save the data initially
229                props = (int *)malloc(NUM_PROPS*sizeof(int));
230                if(props) {
231                        for( i = 0; i < NUM_PROPS; ++i )
232                        {
233                                props[i] = shooting_get_prop(i);
234                        }
235                }
236        }
237}
238
239// Save camera romlog to A/ROMLOG.LOG file
240static void save_romlog(int arg)
241{
242    extern unsigned _ExecuteEventProcedure(const char *name,...);
243
244    if (stat("A/ROMLOG.LOG",0)    == 0) remove("A/ROMLOG.LOG");
245    if (stat("A/RomLogErr.txt",0) == 0) remove("A/RomLogErr.txt");
246
247    unsigned args[3];
248    args[0] = (unsigned)"SystemEventInit";
249    if (call_func_ptr(_ExecuteEventProcedure,args,1) == -1)
250    {
251        args[0] = (unsigned)"System.Create";
252        if (call_func_ptr(_ExecuteEventProcedure,args,1) == -1)
253        {
254            gui_mbox_init(LANG_ERROR, LANG_SAVE_ROMLOG_INIT_ERROR, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
255            return;
256        }
257    }
258
259    args[0] = (unsigned)"GetLogToFile";
260    args[1] = (unsigned)"A/ROMLOG.LOG";
261    args[2] = 1;
262    if (call_func_ptr(_ExecuteEventProcedure,args,3) == -1)
263    {
264        gui_mbox_init(LANG_ERROR, LANG_SAVE_ROMLOG_FAIL, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
265    }
266    else
267    {
268        gui_mbox_init(LANG_INFORMATION, LANG_SAVE_ROMLOG_OK, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
269    }
270}
271
272static const char* gui_debug_shortcut_modes[] =             { "None", "DmpRAM", "Page", "CmpProps"};
273#ifdef CAM_DRYOS
274static const char* gui_debug_display_modes[] =              { "None", "Props", "Params" };
275#else
276static const char* gui_debug_display_modes[] =              { "None", "Props", "Params", "Tasks"};
277#endif
278
279extern volatile int memdmp_delay; // from core/main.c
280
281static void gui_menu_edit_hexa_value(int val) {
282    if (val == 1) {
283        libhexbox->hexbox_init( &conf.memdmp_start, lang_str(LANG_MENU_DEBUG_MEMDMP_START), HEXBOX_FLAG_WALIGN );
284    }
285    else if (val == 2) {
286        libhexbox->hexbox_init( &conf.memdmp_size, lang_str(LANG_MENU_DEBUG_MEMDMP_SIZE), HEXBOX_FLAG_WALIGN );
287    }
288}
289
290static CMenuItem memdmp_submenu_items[] = {
291    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_START,         MENUITEM_PROC,                  gui_menu_edit_hexa_value,           1),
292    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_SIZE,          MENUITEM_PROC,                  gui_menu_edit_hexa_value,           2),
293    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_DELAY,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &memdmp_delay, MENU_MINMAX(0, 10)   ),
294    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
295    {0}
296};
297
298static CMenu memdmp_submenu = {0x2a,LANG_MENU_DEBUG_MEMDMP, NULL, memdmp_submenu_items };
299
300static CMenuItem debug_submenu_items[] = {
301    MENU_ENUM2  (0x5c,LANG_MENU_DEBUG_DISPLAY,              &conf.debug_display,            gui_debug_display_modes ),
302    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_PROPCASE_PAGE,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.debug_propcase_page, MENU_MINMAX(0, 128) ),
303#ifndef CAM_DRYOS
304    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_TASKLIST_START,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &debug_tasklist_start, MENU_MINMAX(0, 63) ),
305#endif
306    MENU_ITEM   (0x5c,LANG_MENU_DEBUG_SHOW_MISC_VALS,       MENUITEM_BOOL,                  &conf.debug_misc_vals_show,         0 ),
307    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMORY_BROWSER,       MENUITEM_PROC,                  module_run,             "memview.flt" ),
308    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_BENCHMARK,            MENUITEM_PROC,                  module_run,             "benchm.flt" ),
309    MENU_ENUM2  (0x5c,LANG_MENU_DEBUG_SHORTCUT_ACTION,      &conf.debug_shortcut_action,    gui_debug_shortcut_modes ),
310    MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP,               MENUITEM_SUBMENU,               &memdmp_submenu,                    0 ),
311    MENU_ITEM   (0x2a,LANG_SAVE_ROMLOG,                     MENUITEM_PROC,                  save_romlog,                        0 ),
312    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
313    {0}
314};
315
316static CMenu debug_submenu = {0x2a,LANG_MENU_DEBUG_TITLE, NULL, debug_submenu_items };
317
318#endif
319
320//-------------------------------------------------------------------
321
322#ifdef CAM_HAS_GPS
323
324// forward reference
325static CMenuItem gps_submenu_items[];
326
327int exit_gpx_record=1;
328int exit_gps_kompass=1;
329int exit_gps_navi=1;
330
331static void gpx_start_stop(int arg)
332{
333    int i = 0;
334    while( gps_submenu_items[i].value != (int*)gpx_start_stop ) i++;    //find entry
335    if( gps_submenu_items[i].text == LANG_MENU_GPS_TRACK_START ) {  //toggle text
336        gps_submenu_items[i].text = LANG_MENU_GPS_TRACK_STOP;
337                exit_gpx_record = 0;
338                init_gpx_record_task();
339
340    } else {
341        gps_submenu_items[i].text = LANG_MENU_GPS_TRACK_START;
342                exit_gpx_record = 1;
343    }
344}
345
346static void show_kompass(int arg)
347{
348    int i = 0;
349    while( gps_submenu_items[i].value != (int*)show_kompass ) i++;    //find entry
350    if( gps_submenu_items[i].text == LANG_MENU_GPS_KOMPASS_SHOW ) {  //toggle text
351        gps_submenu_items[i].text = LANG_MENU_GPS_KOMPASS_HIDE;
352                exit_gps_kompass = 0;
353                init_gps_kompass_task();
354
355    } else {
356        gps_submenu_items[i].text = LANG_MENU_GPS_KOMPASS_SHOW;
357                exit_gps_kompass = 1;
358    }
359}
360
361static void show_navi(int arg)
362{
363    int i = 0;
364    while( gps_submenu_items[i].value != (int*)show_navi ) i++;    //find entry
365    if( gps_submenu_items[i].text == LANG_MENU_GPS_NAVI_SHOW ) {  //toggle text
366        gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HIDE;
367                exit_gpx_record = 0;
368                exit_gps_navi = 0;
369                exit_gps_kompass = 0;
370                init_gps_trackback_task();
371
372    } else {
373        gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_SHOW;
374                exit_gps_navi = 1;
375                exit_gps_kompass = 1;
376                exit_gpx_record = 1;
377    }
378}
379
380static void navigate_home(int arg)
381{
382        int i = 0;
383    while( gps_submenu_items[i].value != (int*)navigate_home ) i++;    //find entry
384    if( gps_submenu_items[i].text == LANG_MENU_GPS_NAVI_HOME ) {  //toggle text
385        gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME_END;
386                exit_gpx_record = 0;
387                exit_gps_navi = 0;
388                exit_gps_kompass = 0;
389                gps_navigate_home();
390
391    } else {
392        gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME;
393                exit_gps_navi = 1;
394                exit_gps_kompass = 1;
395                exit_gpx_record = 1;
396    }
397}
398
399static void mark_timezone(int arg)
400{
401    write_timezone();
402}
403
404static void mark_home(int arg)
405{
406    write_home();
407}
408
409static CMenuItem gps_logging_items[] = {
410    MENU_ITEM   (0x2a,LANG_MENU_GPS_TRACK_TIME,                         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_track_time,           MENU_MINMAX(1, 60) ),
411    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
412    MENU_ITEM   (0x2a,LANG_MENU_GPS_TRACK_SYMBOL,                       MENUITEM_BOOL,                                                                          &conf.gps_track_symbol,         0 ),
413    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
414    MENU_ITEM   (0x2a,LANG_MENU_GPS_REC_PLAY_SET_1,                     MENUITEM_BOOL,                                                                  &conf.gps_rec_play_set_1,       0 ),
415    MENU_ITEM   (0x2a,LANG_MENU_GPS_REC_PLAY_TIME_1,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_rec_play_time_1,      MENU_MINMAX(1, 60) ),
416    MENU_ITEM   (0x2a,LANG_MENU_GPS_PLAY_DARK_SET_1,            MENUITEM_BOOL,                                                                  &conf.gps_play_dark_set_1,      0 ),
417    MENU_ITEM   (0x2a,LANG_MENU_GPS_PLAY_DARK_TIME_1,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_play_dark_time_1,     MENU_MINMAX(1, 60) ),
418    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
419    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
420    {0}
421};
422
423static CMenu gps_logging_submenu = {0x86,LANG_MENU_GPS_LOGGING, NULL, gps_logging_items };
424
425static CMenuItem gps_tagging_items[] = {
426    MENU_ITEM   (0x5c,LANG_MENU_GPS_WAYPOINT_SAVE,          MENUITEM_BOOL,                                          &conf.gps_waypoint_save,    0 ),
427    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
428    MENU_ITEM   (0x2a,LANG_MENU_GPS_WAIT_FOR_SIGNAL,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_wait_for_signal,      MENU_MINMAX(1, 599) ),
429    MENU_ITEM   (0x2a,LANG_MENU_GPS_WAIT_FOR_SIGNAL_TIME,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_wait_for_signal_time, MENU_MINMAX(1, 60) ),
430    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
431    MENU_ITEM   (0x2a,LANG_MENU_GPS_REC_PLAY_SET,                       MENUITEM_BOOL,                                                                  &conf.gps_rec_play_set,         0 ),
432    MENU_ITEM   (0x2a,LANG_MENU_GPS_REC_PLAY_TIME,                      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_rec_play_time,        MENU_MINMAX(1, 60) ),
433    MENU_ITEM   (0x2a,LANG_MENU_GPS_PLAY_DARK_SET,                      MENUITEM_BOOL,                                                                  &conf.gps_play_dark_set,        0 ),
434    MENU_ITEM   (0x2a,LANG_MENU_GPS_PLAY_DARK_TIME,                     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_play_dark_time,       MENU_MINMAX(1, 60) ),
435    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
436    MENU_ITEM   (0x5c,LANG_MENU_GPS_COUNTDOWN,                  MENUITEM_BOOL,                                                                  &conf.gps_countdown     ,               0 ),
437//    MENU_ITEM (0x5c,LANG_MENU_GPS_COUNTDOWN_BLINK,            MENUITEM_BOOL,                                                                  &conf.gps_countdown_blink,      0 ),
438    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
439    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
440    {0}
441};
442
443static CMenu gps_tagging_submenu = {0x86,LANG_MENU_GPS_TAGGING, NULL, gps_tagging_items };
444
445static CMenuItem gps_navigation_items[] = {
446    MENU_ITEM   (0x2a,LANG_MENU_GPS_KOMPASS_SMOOTH,                     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_kompass_smooth,       MENU_MINMAX(1, 40) ),
447    MENU_ITEM   (0x2a,LANG_MENU_GPS_KOMPASS_TIME,                       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_kompass_time,         MENU_MINMAX(1, 60) ),
448    MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVI_TIME,                          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_navi_time,            MENU_MINMAX(1, 60) ),
449    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
450    MENU_ITEM   (0x2a,LANG_MENU_GPS_MARK_HOME,              MENUITEM_PROC,                      (int*)mark_home,                                        0 ),
451    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
452    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
453    {0}
454};
455
456static CMenu gps_navigation_submenu = {0x86,LANG_MENU_GPS_NAVIGATION, NULL, gps_navigation_items };
457
458static const char* gui_gps_sat_fix[] =                  { "immer", "2D", "3D", "2D/3D" };
459
460static CMenuItem gps_values_items[] = {
461    MENU_ITEM   (0x2a,LANG_MENU_GPS_BATT,                                       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_batt,                         MENU_MINMAX(0, 99) ),
462    MENU_ITEM   (0x2a,LANG_MENU_GPS_BATT_WARNING,                       MENUITEM_BOOL,                                                                          &conf.gps_batt_warn,            0 ),
463    MENU_ITEM   (0x2a,LANG_MENU_GPS_BEEP_WARNING,                       MENUITEM_BOOL,                                                                          &conf.gps_beep_warn,            0 ),
464    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
465    MENU_ENUM2  (0x69,LANG_MENU_GPS_2D_3D_FIX,                          &conf.gps_2D_3D_fix,                                                            gui_gps_sat_fix ),
466    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
467    MENU_ITEM   (0x2a,LANG_MENU_GPS_SYMBOL_SHOW,                        MENUITEM_BOOL,                                                                          &conf.gps_show_symbol,          0 ),
468    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
469    MENU_ITEM   (0x2a,LANG_MENU_GPS_TEST_TIMEZONE,                      MENUITEM_BOOL,                                                                          &conf.gps_test_timezone,        0 ),
470    MENU_ITEM   (0x2a,LANG_MENU_GPS_MARK_TIMEZONE,          MENUITEM_PROC,                                          (int*)mark_timezone,                0 ),
471    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                             0,                                                  0 ),
472    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
473    {0}
474};
475
476static CMenu gps_values_submenu = {0x86,LANG_MENU_GPS_VALUES, NULL, gps_values_items };
477
478static CMenuItem gps_submenu_items[] = {
479    MENU_ITEM   (0x2a,LANG_MENU_GPS_ON_OFF,                                     MENUITEM_BOOL,                                  &conf.gps_on_off,                                       0 ),
480    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
481    MENU_ITEM   (0x2a,LANG_MENU_GPS_KOMPASS_SHOW,           MENUITEM_PROC,                              (int*)show_kompass,                                     0 ),
482    MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVI_SHOW,              MENUITEM_PROC,                      (int*)show_navi,                                        0 ),
483    MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVI_HOME,              MENUITEM_PROC,                      (int*)navigate_home,                            0 ),
484    MENU_ITEM   (0x2a,LANG_MENU_GPS_TRACK_START,            MENUITEM_PROC,                      (int*)gpx_start_stop,                           0 ),
485    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
486    MENU_ITEM   (0x2a,LANG_MENU_GPS_VALUES,                     MENUITEM_SUBMENU,               &gps_values_submenu,                    0 ),
487    MENU_ITEM   (0x2a,LANG_MENU_GPS_LOGGING,                    MENUITEM_SUBMENU,               &gps_logging_submenu,                   0 ),
488    MENU_ITEM   (0x2a,LANG_MENU_GPS_TAGGING,                    MENUITEM_SUBMENU,               &gps_tagging_submenu,                   0 ),
489    MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVIGATION,                 MENUITEM_SUBMENU,               &gps_navigation_submenu,            0 ),
490    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
491    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                        0,                                  0 ),
492    {0}
493};
494
495static CMenu gps_submenu = {0x2a,LANG_MENU_GPS, NULL, gps_submenu_items };
496
497#endif
498
499//-------------------------------------------------------------------
500
501static void gui_draw_read_selected(const char *fn)
502{
503    if (fn)
504    {
505                libtxtread->read_file(fn);
506    }
507}
508
509static void gui_draw_read(int arg)
510{
511    libfselect->file_select(LANG_STR_SELECT_TEXT_FILE, conf.reader_file, "A/CHDK/BOOKS", gui_draw_read_selected);
512}
513
514static void gui_draw_read_last(int arg)
515{
516    if (stat(conf.reader_file,0) == 0)
517        gui_draw_read_selected(conf.reader_file);
518    else
519        gui_draw_read(arg);
520}
521
522static void gui_draw_rbf_selected(const char *fn)
523{
524    if (fn) {
525        strcpy(conf.reader_rbf_file, fn);
526    }
527}
528
529static void gui_draw_load_rbf(int arg)
530{
531    libfselect->file_select(LANG_STR_SELECT_FONT_FILE, conf.reader_rbf_file, "A/CHDK/FONTS", gui_draw_rbf_selected);
532}
533
534static const char* gui_reader_codepage_cps[] = { "Win1251", "DOS"};
535static CMenuItem reader_submenu_items[] = {
536    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_NEW,           MENUITEM_PROC,    gui_draw_read, 0 ),
537    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_LAST,          MENUITEM_PROC,    gui_draw_read_last, 0 ),
538    MENU_ITEM(0x35,LANG_MENU_READ_SELECT_FONT,        MENUITEM_PROC,    gui_draw_load_rbf, 0 ),
539    MENU_ENUM2(0x5f,LANG_MENU_READ_CODEPAGE,          &conf.reader_codepage, gui_reader_codepage_cps ),
540    MENU_ITEM(0x5c,LANG_MENU_READ_WORD_WRAP,          MENUITEM_BOOL,    &conf.reader_wrap_by_words, 0 ),
541    MENU_ITEM(0x5c,LANG_MENU_READ_AUTOSCROLL,         MENUITEM_BOOL,    &conf.reader_autoscroll, 0 ),
542    MENU_ITEM(0x5f,LANG_MENU_READ_AUTOSCROLL_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.reader_autoscroll_delay, MENU_MINMAX(0, 60) ),
543    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
544    {0}
545};
546
547static CMenu reader_submenu = {0x37,LANG_MENU_READ_TITLE, NULL, reader_submenu_items };
548
549//-------------------------------------------------------------------
550#if defined (OPT_GAMES)
551
552static CMenuItem games_submenu_items[] = {
553    MENU_ITEM(0x38,LANG_MENU_GAMES_REVERSI,           MENUITEM_PROC,  module_run, "reversi.flt" ),
554    MENU_ITEM(0x38,LANG_MENU_GAMES_SOKOBAN,           MENUITEM_PROC,  module_run, "sokoban.flt" ),
555    MENU_ITEM(0x38,LANG_MENU_GAMES_CONNECT4,          MENUITEM_PROC,  module_run, "4wins.flt" ),
556    MENU_ITEM(0x38,LANG_MENU_GAMES_MASTERMIND,        MENUITEM_PROC,  module_run, "mastmind.flt" ),
557    MENU_ITEM(0x38,"Snake" ,                          MENUITEM_PROC,  module_run, "snake.flt" ),
558    MENU_ITEM(0x38,"Tetris",                          MENUITEM_PROC,  module_run, "tetris.flt" ),
559        MENU_ITEM(0x38,"Sudoku",                                                  MENUITEM_PROC,  module_run, "sudoku.flt" ),
560    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
561    {0}
562};
563
564static CMenu games_submenu = {0x38,LANG_MENU_GAMES_TITLE, NULL, games_submenu_items };
565
566#endif
567//-------------------------------------------------------------------
568
569static void gui_menuproc_mkbootdisk(int arg)
570{
571    mark_filesystem_bootable();
572    gui_mbox_init(LANG_INFORMATION, LANG_CONSOLE_TEXT_FINISHED, MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, NULL);
573}
574
575#if CAM_MULTIPART
576
577static void card_break_proc(unsigned int btn)
578{
579    if (btn==MBOX_BTN_YES) create_partitions();
580}
581
582static void gui_menuproc_break_card(int arg)
583{
584    gui_mbox_init(LANG_WARNING, LANG_PARTITIONS_CREATE_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, card_break_proc);
585}
586
587static char* partitions_enum=NULL;
588
589static const char* gui_menuproc_swap_partitions_enum(int change, int arg)
590{
591    int new_partition;
592    int partition_count = get_part_count();
593    char vBuf[16];
594    if(partitions_enum)
595    {
596      free(partitions_enum);
597      partitions_enum=NULL;
598    }
599    new_partition= get_active_partition()+change;
600    if( new_partition <=0)
601    {
602      new_partition = partition_count;
603    }
604    else if( new_partition > partition_count)
605    {
606      new_partition = 1;
607    } 
608    sprintf(vBuf,"%d/%d",new_partition, partition_count);
609    partitions_enum=malloc((strlen(vBuf)+1)*sizeof(char));
610    strcpy(partitions_enum,vBuf);
611
612    if(change != 0)
613    {
614      swap_partitions(new_partition);
615    }
616    return partitions_enum;
617}
618
619#endif
620
621static CMenuItem sdcard_submenu_items[] = {
622    MENU_ITEM   (0x33,LANG_MENU_DEBUG_MAKE_BOOTABLE,        MENUITEM_PROC,                  gui_menuproc_mkbootdisk, 0 ),
623#if CAM_MULTIPART
624    MENU_ITEM   (0x33,LANG_MENU_DEBUG_CREATE_MULTIPART ,    MENUITEM_PROC,                  gui_menuproc_break_card,            0 ),
625    MENU_ITEM   (0x33,LANG_MENU_DEBUG_SWAP_PART,            MENUITEM_ENUM,                  gui_menuproc_swap_partitions_enum,  0 ),
626#endif
627    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
628    {0},
629};
630
631static CMenu sdcard_submenu = {0x33,LANG_SD_CARD, NULL, sdcard_submenu_items };
632
633//-------------------------------------------------------------------
634
635static void gui_delete_module_log_callback(unsigned int btn)
636{
637    if (btn == MBOX_BTN_YES)
638        module_log_clear();
639}
640
641static void gui_delete_module_log(int arg)
642{
643    gui_mbox_init(LANG_WARNING, LANG_MENU_DELETE_MODULE_LOG, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, gui_delete_module_log_callback);
644}
645
646static CMenuItem module_submenu_items[] = {
647    MENU_ITEM   (0x80,LANG_MENU_MODULE_INSPECTOR,           MENUITEM_PROC,                  module_run, "modinsp.flt" ),
648    MENU_ITEM   (0x5c,LANG_MENU_MODULE_LOGGING,             MENUITEM_BOOL,                  &conf.module_logging, 0 ),
649    MENU_ITEM   (0x2b,LANG_MENU_DELETE_MODULE_LOG,          MENUITEM_PROC,                  gui_delete_module_log, 0 ),
650    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0, 0 ),
651    {0},
652};
653
654static CMenu module_submenu = {0x28,LANG_MENU_MODULES, NULL, module_submenu_items };
655
656//-------------------------------------------------------------------
657
658static void gui_draw_fselect(int arg)
659{
660    libfselect->file_select(LANG_STR_FILE_BROWSER, "A", "A", NULL);
661}
662
663static void gui_show_build_info(int arg)
664{
665    static char comp[64];
666
667#ifdef __GNUC__
668# ifndef __GNUC_PATCHLEVEL__
669# define __GNUC_PATCHLEVEL 0
670# endif
671    sprintf(comp, "GCC %d.%d.%d", __GNUC__ ,__GNUC_MINOR__,__GNUC_PATCHLEVEL__ );
672#else
673    sprintf(comp, "UNKNOWN" );
674#endif
675    sprintf(buf, lang_str(LANG_MSG_BUILD_INFO_TEXT), camera_info.chdk_ver, camera_info.build_number, camera_info.build_svnrev, camera_info.build_date, camera_info.build_time, camera_info.platform, camera_info.platformsub, comp);
676    gui_mbox_init(LANG_MSG_BUILD_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_LEFT, NULL);
677}
678
679static void gui_show_memory_info(int arg)
680{
681    sprintf(buf, lang_str(LANG_MSG_MEMORY_INFO_TEXT), core_get_free_memory(), camera_info.memisosize, &_start, &_end);
682    gui_mbox_init(LANG_MSG_MEMORY_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
683}
684
685#if !defined(OPT_FORCE_LUA_CALL_NATIVE)
686static void lua_native_call_warning(unsigned int btn)
687{
688    if (btn==MBOX_BTN_NO)
689        conf.script_allow_lua_native_calls = 0;
690}
691
692static void gui_lua_native_call_warning(int arg)
693{
694    if (conf.script_allow_lua_native_calls)
695        gui_mbox_init(LANG_WARNING, LANG_MENU_LUA_NATIVE_CALLS_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER, lua_native_call_warning);
696}
697#endif
698
699static const char* gui_console_show_enum[]={ "ALT", "Always" };
700
701static void gui_console_clear(int arg)
702{
703    console_close();
704    gui_mbox_init(LANG_MENU_CONSOLE_CLEAR, LANG_MENU_CONSOLE_RESET, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
705}
706
707static void gui_console_show(int arg)
708{
709    void display_console();
710    display_console();
711}
712
713static CMenuItem console_settings_submenu_items[] = {
714    MENU_ENUM2(0x5f,LANG_MENU_CONSOLE_SHOWIN,       &conf.console_show,         gui_console_show_enum ),
715    MENU_ITEM(0x58,LANG_MENU_CONSOLE_TIMEOUT,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.console_timeout, MENU_MINMAX(3, 30) ),
716    MENU_ITEM(0x35,LANG_MENU_CONSOLE_SHOW,          MENUITEM_PROC,              gui_console_show, 0 ),
717    MENU_ITEM(0x35,LANG_MENU_CONSOLE_CLEAR,         MENUITEM_PROC,              gui_console_clear, 0 ),
718    MENU_ITEM(0x51,LANG_MENU_BACK,                  MENUITEM_UP, 0, 0 ),
719    {0}
720};
721
722static CMenu console_settings_submenu = {0x28,LANG_MENU_CONSOLE_SETTINGS, NULL, console_settings_submenu_items };
723
724static CMenuItem misc_submenu_items[] = {
725    MENU_ITEM   (0x35,LANG_MENU_MISC_FILE_BROWSER,          MENUITEM_PROC,                  gui_draw_fselect,                   0 ),
726    MENU_ITEM   (0x28,LANG_MENU_MODULES,                    MENUITEM_SUBMENU,               &module_submenu,                    0 ),
727    MENU_ITEM   (0x36,LANG_MENU_MISC_CALENDAR,              MENUITEM_PROC,                  module_run, "calend.flt" ),
728    MENU_ITEM   (0x37,LANG_MENU_MISC_TEXT_READER,           MENUITEM_SUBMENU,               &reader_submenu,                    0 ),
729#if defined (OPT_GAMES)
730    MENU_ITEM   (0x38,LANG_MENU_MISC_GAMES,                 MENUITEM_SUBMENU,               &games_submenu,                     0 ),
731#endif
732    MENU_ITEM   (0x28,LANG_MENU_CONSOLE_SETTINGS,           MENUITEM_SUBMENU,               &console_settings_submenu, 0 ),
733#if CAM_SWIVEL_SCREEN
734    MENU_ITEM   (0x5c,LANG_MENU_MISC_FLASHLIGHT,            MENUITEM_BOOL,                  &conf.flashlight, 0 ),
735#endif
736    MENU_ITEM   (0x80,LANG_MENU_MISC_BUILD_INFO,            MENUITEM_PROC,                  gui_show_build_info, 0 ),
737    MENU_ITEM   (0x80,LANG_MENU_MISC_MEMORY_INFO,           MENUITEM_PROC,                  gui_show_memory_info, 0 ),
738#if !defined(OPT_FORCE_LUA_CALL_NATIVE)
739    MENU_ITEM   (0x5c,LANG_MENU_ENABLE_LUA_NATIVE_CALLS,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK, &conf.script_allow_lua_native_calls, (int)gui_lua_native_call_warning ),
740#endif
741    MENU_ITEM   (0x33,LANG_SD_CARD,                         MENUITEM_SUBMENU,               &sdcard_submenu,                    0 ),
742#ifdef OPT_DEBUGGING
743    MENU_ITEM   (0x2a,LANG_MENU_MAIN_DEBUG,                 MENUITEM_SUBMENU,               &debug_submenu,                     0 ),
744#endif
745    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
746    {0},
747};
748
749static CMenu misc_submenu = {0x29,LANG_MENU_MISC_TITLE, NULL, misc_submenu_items };
750
751//-------------------------------------------------------------------
752
753static void cb_perc()
754{
755    conf.batt_volts_show=0;
756}
757
758static void cb_volts()
759{
760    conf.batt_perc_show=0;
761}
762
763static void cb_battery_menu_change(unsigned int item)
764{
765    switch (item) {
766        case 0: //Voltage MAX
767            if (conf.batt_volts_max<conf.batt_volts_min+25) {
768                conf.batt_volts_min = conf.batt_volts_max-25;
769            }
770            break;
771        case 1: //Voltage MIN
772            if (conf.batt_volts_min>conf.batt_volts_max-25) {
773                conf.batt_volts_max = conf.batt_volts_min+25;
774            }
775            break;
776        default:
777            break;
778    }
779}
780
781static CMenuItem battery_submenu_items[] = {
782    MENU_ITEM   (0x66,LANG_MENU_BATT_VOLT_MAX,              MENUITEM_INT,                           &conf.batt_volts_max,   0 ),
783    MENU_ITEM   (0x67,LANG_MENU_BATT_VOLT_MIN,              MENUITEM_INT,                           &conf.batt_volts_min,   0 ),
784    MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                     0,                      0 ),
785    MENU_ITEM   (0x73,LANG_MENU_BATT_SHOW_PERCENT,          MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_perc_show,   (int)cb_perc ),
786    MENU_ITEM   (0x73,LANG_MENU_BATT_SHOW_VOLTS,            MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_volts_show,  (int)cb_volts ),
787    MENU_ITEM   (0x32,LANG_MENU_BATT_SHOW_ICON,             MENUITEM_BOOL,                          &conf.batt_icon_show,   0 ),
788    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                            0,                      0 ),
789    {0}
790};
791
792static CMenu battery_submenu = {0x32,LANG_MENU_BATT_TITLE, cb_battery_menu_change, battery_submenu_items };
793
794//-------------------------------------------------------------------
795
796void cb_space_perc()
797{
798    conf.space_mb_show=0;
799}
800
801void cb_space_mb()
802{
803    conf.space_perc_show=0;
804}
805
806static const char* gui_space_bar_modes[] =                  { "Don't", "Horizontal", "Vertical"};
807static const char* gui_space_bar_size_modes[] =             { "1/4", "1/2", "1"};
808static const char* gui_space_bar_width_modes[] =            { "1", "2", "3","4","5","6","7","8","9","10"};
809static const char* gui_space_warn_type_modes[] =            { "Percent", "MB", "Don't"};
810
811static CMenuItem space_submenu_items[] = {
812    MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_ICON,            MENUITEM_BOOL,                          &conf.space_icon_show,  0 ),
813    MENU_ENUM2  (0x69,LANG_MENU_SPACE_SHOW_BAR,             &conf.space_bar_show,                   gui_space_bar_modes ),
814    MENU_ENUM2  (0x6a,LANG_MENU_SPACE_BAR_SIZE,             &conf.space_bar_size,                   gui_space_bar_size_modes ),
815    MENU_ENUM2  (0x6b,LANG_MENU_SPACE_BAR_WIDTH,            &conf.space_bar_width,                  gui_space_bar_width_modes ),
816    MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_PERCENT,         MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_perc_show, (int)cb_space_perc ),
817    MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_MB,              MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_mb_show,   (int)cb_space_mb ),
818#if CAM_MULTIPART
819    MENU_ITEM   (0x5c,LANG_MENU_SHOW_PARTITION_NR,          MENUITEM_BOOL,                          &conf.show_partition_nr, 0 ),
820#endif
821    MENU_ENUM2  (0x5f,LANG_MENU_SPACE_WARN_TYPE,            &conf.space_warn_type,                  gui_space_warn_type_modes ),
822    MENU_ITEM   (0x58,LANG_MENU_SPACE_WARN_PERCENT,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_perc_warn,    MENU_MINMAX(1, 99) ),
823    MENU_ITEM   (0x58,LANG_MENU_SPACE_WARN_MB,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_mb_warn,      MENU_MINMAX(1, 4000) ),
824    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                      0 ),
825    {0}
826};
827
828static CMenu space_submenu = {0x33,LANG_MENU_OSD_SPACE_PARAMS_TITLE, NULL, space_submenu_items};
829
830//-------------------------------------------------------------------
831
832static const char* gui_dof_show_value_modes[] =             { "Don't", "Separate", "+Separate", "In Misc", "+In Misc" };
833
834static CMenuItem dof_submenu_items[] = {
835    MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_DOF_CALC,          &conf.show_dof,     gui_dof_show_value_modes ),
836    MENU_ITEM   (0x5c,LANG_MENU_DOF_SUBJ_DIST_AS_NEAR_LIMIT,MENUITEM_BOOL,      &conf.dof_subj_dist_as_near_limit,  0 ),
837    MENU_ITEM   (0x5c,LANG_MENU_DOF_USE_EXIF_SUBJ_DIST,     MENUITEM_BOOL,      &conf.dof_use_exif_subj_dist,       0 ),
838    MENU_ITEM   (0x5c,LANG_MENU_DOF_SUBJ_DIST_IN_MISC,      MENUITEM_BOOL,      &conf.dof_subj_dist_in_misc,        0 ),
839    MENU_ITEM   (0x5c,LANG_MENU_DOF_NEAR_LIMIT_IN_MISC,     MENUITEM_BOOL,      &conf.dof_near_limit_in_misc,       0 ),
840    MENU_ITEM   (0x5c,LANG_MENU_DOF_FAR_LIMIT_IN_MISC,      MENUITEM_BOOL,      &conf.dof_far_limit_in_misc,        0 ),
841    MENU_ITEM   (0x5c,LANG_MENU_DOF_HYPERFOCAL_IN_MISC,     MENUITEM_BOOL,      &conf.dof_hyperfocal_in_misc,       0 ),
842    MENU_ITEM   (0x5c,LANG_MENU_DOF_DEPTH_LIMIT_IN_MISC,    MENUITEM_BOOL,      &conf.dof_depth_in_misc,            0 ),
843    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                  0 ),
844    {0}
845};
846
847static CMenu dof_submenu = {0x31,LANG_MENU_DOF_TITLE, /*cb_dof_menu_change*/ NULL, dof_submenu_items };
848
849//-------------------------------------------------------------------
850
851static const char* gui_zoom_value_modes[] =                 { "X", "FL", "EFL" };
852static const char* gui_show_values_modes[] =                { "Don't", "Always", "Shoot" };
853
854static CMenuItem values_submenu_items[] = {
855    MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_MISC_VALUES,       &conf.show_values,  gui_show_values_modes ),
856    MENU_ITEM   (0x5c,LANG_MENU_SHOW_VALUES_IN_VIDEO,       MENUITEM_BOOL,      &conf.show_values_in_video,                 0 ),
857    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_ZOOM,           MENUITEM_BOOL,      &conf.values_show_zoom,                     0 ),
858    MENU_ENUM2  (0x5f,LANG_MENU_OSD_ZOOM_VALUE,             &conf.zoom_value,   gui_zoom_value_modes ),
859    MENU_ITEM   (0x60,LANG_MENU_OSD_ZOOM_SCALE,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zoom_scale,   MENU_MINMAX(0, 1000) ),
860    MENU_ITEM   (0x62,LANG_MENU_VALUES_SHOW_REAL_APERTURE,  MENUITEM_BOOL,      &conf.values_show_real_aperture,            0 ),
861    MENU_ITEM   (0x74,LANG_MENU_VALUES_SHOW_REAL_ISO,       MENUITEM_BOOL,      &conf.values_show_real_iso,                 0 ),
862    MENU_ITEM   (0x74,LANG_MENU_VALUES_SHOW_MARKET_ISO,     MENUITEM_BOOL,      &conf.values_show_market_iso,               0 ),
863    MENU_ITEM   (0x2d,LANG_MENU_SHOW_ISO_ONLY_IN_AUTOISO_MODE, MENUITEM_BOOL,   &conf.values_show_iso_only_in_autoiso_mode, 0 ),
864    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_EV_SETED,       MENUITEM_BOOL,      &conf.values_show_ev_seted,                 0 ),
865    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_EV_MEASURED,    MENUITEM_BOOL,      &conf.values_show_ev_measured,              0 ),
866    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_BV_SETED,       MENUITEM_BOOL,      &conf.values_show_bv_seted,                 0 ),
867    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_BV_MEASURED,    MENUITEM_BOOL,      &conf.values_show_bv_measured,              0 ),
868    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_OVEREXPOSURE,   MENUITEM_BOOL,      &conf.values_show_overexposure,             0 ),
869    MENU_ITEM   (0x5c,LANG_MENU_SHOW_CANON_OVEREXPOSURE,    MENUITEM_BOOL,      &conf.values_show_canon_overexposure,       0 ),
870    MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_LUMINANCE,      MENUITEM_BOOL,      &conf.values_show_luminance,                0 ),
871    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                          0 ),
872    {0}
873};
874
875static CMenu values_submenu = {0x28,LANG_MENU_OSD_VALUES_TITLE, /*cb_values_menu_change*/ NULL, values_submenu_items };
876
877//-------------------------------------------------------------------
878
879static const char* gui_show_clock_modes[]=                  { "Don't", "Normal", "Seconds"};
880static const char* gui_clock_format_modes[] =               { "24h", "12h"};
881static const char* gui_clock_indicator_modes[] =            { "PM", "P", "."};
882static const char* gui_clock_halfpress_modes[] =            { "Full", "Seconds", "Don't"};
883
884static CMenuItem clock_submenu_items[] = {
885    MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_CLOCK,             &conf.show_clock,       gui_show_clock_modes ),
886    MENU_ENUM2  (0x6d,LANG_MENU_OSD_CLOCK_FORMAT,           &conf.clock_format,     gui_clock_format_modes ),
887    MENU_ENUM2  (0x6c,LANG_MENU_OSD_CLOCK_INDICATOR,        &conf.clock_indicator,  gui_clock_indicator_modes ),
888    MENU_ENUM2  (0x6e,LANG_MENU_OSD_CLOCK_HALFPRESS,        &conf.clock_halfpress,  gui_clock_halfpress_modes ),
889    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                              0 ),
890    {0}
891};
892
893static CMenu clock_submenu = {0x34,LANG_MENU_OSD_CLOCK_PARAMS_TITLE, NULL, clock_submenu_items };
894
895//-------------------------------------------------------------------
896
897#if !CAM_VIDEO_QUALITY_ONLY
898const char* gui_video_bitrate_enum(int change, int arg)
899{
900    static const char *modes[]={ "0.25x", "0.5x","0.75x", "1x", "1.25x", "1.5x", "1.75x", "2x", "2.5x", "3x"};
901        gui_enum_value_change(&conf.video_bitrate,change,sizeof(modes)/sizeof(modes[0]));
902
903    if (change)
904        shooting_video_bitrate_change(conf.video_bitrate);
905
906    return modes[conf.video_bitrate];
907}
908#endif
909 
910#if CAM_AF_SCAN_DURING_VIDEO_RECORD
911static const char* gui_video_af_key_enum(int change, int arg)
912{
913    static const char* names[] = CAM_VIDEO_AF_BUTTON_NAMES;
914    static const int keys[] = CAM_VIDEO_AF_BUTTON_OPTIONS;
915    int i;
916 
917    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
918        if (conf.video_af_key==keys[i]) {
919            break;
920        }
921    }
922 
923    i+=change;
924    if (i<0)
925        i=(sizeof(names)/sizeof(names[0]))-1;
926    else if (i>=(sizeof(names)/sizeof(names[0])))
927        i=0;
928 
929    conf.video_af_key = keys[i];
930    return names[i];
931}
932#endif
933
934static const char* gui_show_movie_time_modes[] =            { "Don't", "hh:mm:ss", "KB/s","both"};
935#if !CAM_VIDEO_QUALITY_ONLY
936    static const char* gui_video_mode_modes[] =             { "Bitrate", "Quality"};
937#else
938    static const char* gui_video_mode_modes[] =             { "Default", "Quality"};
939#endif
940
941static CMenuItem video_submenu_items[] = {
942#if CAM_CHDK_HAS_EXT_VIDEO_MENU
943    MENU_ENUM2  (0x23,LANG_MENU_VIDEO_MODE,                 &conf.video_mode,       gui_video_mode_modes ),
944#if !CAM_VIDEO_QUALITY_ONLY
945    MENU_ITEM   (0x5e,LANG_MENU_VIDEO_BITRATE,              MENUITEM_ENUM,          gui_video_bitrate_enum,             0 ),
946#endif
947    MENU_ITEM   (0x60,LANG_MENU_VIDEO_QUALITY,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.video_quality, MENU_MINMAX(1, 99) ),
948#if CAM_CHDK_HAS_EXT_VIDEO_TIME
949    MENU_ITEM   (0x5c,LANG_MENU_VIDEO_EXT_TIME,             MENUITEM_BOOL,          &conf.ext_video_time,               0 ),
950#endif
951    MENU_ITEM   (0x5c,LANG_MENU_CLEAR_VIDEO_VALUES,         MENUITEM_BOOL,          &conf.clear_video,                  0 ),
952#endif
953#if CAM_VIDEO_CONTROL
954    MENU_ITEM   (0x5c,LANG_MENU_FAST_SWITCH_VIDEO,          MENUITEM_BOOL,          &conf.fast_movie_control,           0 ),
955#endif
956#if CAM_CHDK_HAS_EXT_VIDEO_MENU
957    MENU_ITEM   (0x5c,LANG_MENU_FAST_SWITCH_QUALITY_VIDEO,  MENUITEM_BOOL,          &conf.fast_movie_quality_control,   0 ),
958#endif
959#if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
960    MENU_ITEM   (0x5c,LANG_MENU_OPTICAL_ZOOM_IN_VIDEO,      MENUITEM_BOOL,          &conf.unlock_optical_zoom_for_video, 0 ),
961#endif
962#if CAM_CAN_MUTE_MICROPHONE
963    MENU_ITEM   (0x83,LANG_MENU_MUTE_ON_ZOOM,               MENUITEM_BOOL,          &conf.mute_on_zoom,                 0 ),
964#endif
965#if CAM_AF_SCAN_DURING_VIDEO_RECORD
966    MENU_ITEM   (0x82,LANG_MENU_VIDEO_AF_KEY,               MENUITEM_ENUM,          gui_video_af_key_enum,              0 ),
967#endif
968    MENU_ENUM2  (0x5c,LANG_MENU_OSD_SHOW_VIDEO_TIME,        &conf.show_movie_time,  gui_show_movie_time_modes ),
969    MENU_ITEM   (0x60,LANG_MENU_OSD_SHOW_VIDEO_REFRESH,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.show_movie_refresh,   MENU_MINMAX(1, 20) ),
970    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                                  0 ),
971    {0}
972};
973
974static CMenu video_submenu = {0x23,LANG_MENU_VIDEO_PARAM_TITLE, NULL, video_submenu_items };
975
976//-------------------------------------------------------------------
977// "Extra Photo Operations" Menu
978
979static const char* tv_override[]={
980#ifdef CAM_EXT_TV_RANGE
981    // add very long time exposures as approximately powers of 2, adding 15 exposures
982    "2048","1625","1290","1024","812","645","512","406","322","256","203","161","128","101","80",
983#endif
984    "64","50.8", "40.3", "32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2",
985    "1.6", "1.3", "1", "0.8", "0.6", "0.5", "0.4", "0.3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13",
986    "1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200",
987    "1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500",
988    "1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000",
989    "1/32000", "1/40000", "1/50000", "1/64000","1/80000", "1/100k"
990};
991
992const char* gui_tv_override_value_enum(int change, int arg)
993{
994    gui_enum_value_change(&conf.tv_override_value,change,sizeof(tv_override)/sizeof(tv_override[0]));
995    return tv_override[conf.tv_override_value];
996}
997
998static const char* gui_tv_enum_type_enum(int change, int arg)
999{
1000#ifdef CAM_EXT_TV_RANGE
1001    static const char* modes[ ]= { "Ev Step", "ShrtExp", "LongExp" };
1002#else
1003    static const char* modes[ ]= { "Ev Step", "ShrtExp" };
1004#endif
1005
1006    gui_enum_value_change(&conf.tv_enum_type,change,sizeof(modes)/sizeof(modes[0]));
1007    if (change)
1008    {
1009        void set_tv_override_menu();
1010        set_tv_override_menu();
1011    }
1012    return modes[conf.tv_enum_type];
1013}
1014
1015#if CAM_HAS_IRIS_DIAPHRAGM
1016const char* gui_av_override_enum(int change, int arg)
1017{
1018    conf.av_override_value+=change;
1019    if (conf.av_override_value<0) conf.av_override_value=shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1;
1020    else if (conf.av_override_value>shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1) conf.av_override_value=0;
1021
1022    short prop_id=shooting_get_aperture_from_av96(shooting_get_av96_override_value());
1023    sprintf(buf, "%d.%02d", (int)prop_id/100, (int)prop_id%100 );
1024    return buf;
1025}
1026#endif
1027
1028#if ZOOM_OVERRIDE
1029const char* gui_zoom_override_enum(int change, int arg)
1030{
1031    conf.zoom_override_value+=change;
1032    if (conf.zoom_override_value<0) conf.zoom_override_value=zoom_points-1;
1033    else if (conf.zoom_override_value>zoom_points-1) conf.zoom_override_value=0;
1034    sprintf(buf,"%i",conf.zoom_override_value);
1035    return buf;
1036}
1037#endif
1038
1039const char* gui_subj_dist_override_value_enum(int change, int arg)
1040{
1041    static char buf[9];
1042
1043    if (conf.subj_dist_override_koef == SD_OVERRIDE_INFINITY)  // Infinity selected
1044        strcpy(buf,"   Inf.");
1045    else
1046    {
1047        // Increment / decrement the SD value, wrapping around from MIN_DIST to MAX_DIST
1048        conf.subj_dist_override_value += (change/**koef*/);
1049        if (conf.subj_dist_override_value < MIN_DIST)
1050            conf.subj_dist_override_value = MAX_DIST;
1051        else if (conf.subj_dist_override_value > MAX_DIST)
1052            conf.subj_dist_override_value = MIN_DIST;
1053        sprintf(buf, "%7d", shooting_get_subject_distance_override_value());
1054    }
1055
1056    return buf;
1057}
1058
1059const char* gui_subj_dist_override_koef_enum(int change, int arg)
1060{
1061    static const char* modes[] = { "Off", "On", "Inf" };
1062        const char *rv = gui_change_simple_enum(&conf.subj_dist_override_koef,change,modes,sizeof(modes)/sizeof(modes[0]));
1063    return rv;
1064}
1065
1066#if defined(OPT_CURVES)
1067
1068static const char* gui_conf_curve_enum(int change, int arg) {
1069    static const char* modes[]={ "None", "Custom", "+1EV", "+2EV", "Auto DR" };
1070
1071    gui_enum_value_change(&conf.curve_enable,change,sizeof(modes)/sizeof(modes[0]));
1072
1073        if (change)
1074        libcurves->curve_init_mode();
1075    return modes[conf.curve_enable];
1076}
1077
1078static void gui_load_curve_selected(const char *fn)
1079{
1080        if (fn) {
1081                // TODO we could sanity check here, but curve_set_type should fail gracefullish
1082                strcpy(conf.curve_file,fn);
1083                if (conf.curve_enable == 1)
1084            libcurves->curve_init_mode();
1085        }
1086}
1087
1088static void gui_load_curve(int arg)
1089{
1090    libfselect->file_select(LANG_STR_SELECT_CURVE_FILE, conf.curve_file, CURVE_DIR, gui_load_curve_selected);
1091}
1092
1093static CMenuItem curve_submenu_items[] = {
1094    MENU_ITEM(0x5f,LANG_MENU_CURVE_ENABLE,        MENUITEM_ENUM,      gui_conf_curve_enum, &conf.curve_enable ),
1095    MENU_ITEM(0x35,LANG_MENU_CURVE_LOAD,          MENUITEM_PROC,      gui_load_curve, 0 ),
1096    MENU_ITEM(0x51,LANG_MENU_BACK,                MENUITEM_UP, 0, 0 ),
1097    {0}
1098};
1099
1100static CMenu curve_submenu = {0x85,LANG_MENU_CURVE_PARAM_TITLE, NULL, curve_submenu_items };
1101
1102#endif
1103
1104// Display & edit an int value as a decimal.
1105// Value ranges from 0 - 100000; but display shows as 0.00000 - 1.00000
1106const char* gui_decimal_enum(int change, int arg)
1107{
1108    int *v = (int*)arg;
1109
1110    *v += change;
1111    if (*v < 0) *v = 0;
1112    if (*v > 100000) *v = 100000;
1113
1114    sprintf(buf, "%01d.%05d", (int)(*v / 100000), (int)(*v % 100000));
1115
1116    return buf;
1117}
1118
1119// Modify and display a value as H:MM:SS
1120// For storing a value as a number of seconds internally; but displaying as a time value
1121const char* gui_hhmss_enum(int change, int arg)
1122{
1123    int *v = (int*)arg;
1124
1125    int h, m, s;
1126    h = *v / 3600;
1127    m = (*v % 3600) / 60;
1128    s = *v % 60;
1129
1130    switch (change)
1131    {
1132    case 1:
1133    case -1:
1134        s += change;
1135        if (s < 0) s = 59;
1136        if (s > 59) s = 0;
1137        break;
1138    case 10:
1139    case -10:
1140        m += change / 10;
1141        if (m < 0) m = 59;
1142        if (m > 59) m = 0;
1143        break;
1144    default:
1145        h += change /100;
1146        if (h < 0) h = 1;
1147        if (h > 1) h = 0;
1148        break;
1149    }
1150    *v = (h * 3600) + (m * 60) + s;
1151
1152    sprintf(buf, "%1d:%02d:%02d", h, m, s);
1153
1154    return buf;
1155}
1156
1157static const char* gui_override_disable_modes[] =           { "No", "Yes" };
1158static const char* gui_flash_power_modes[] =                { "Min", "Med", "Max" };
1159#if CAM_HAS_ND_FILTER
1160static const char* gui_nd_filter_state_modes[] =            { "Off", "In", "Out" };
1161#endif
1162static const char* gui_fast_ev_step_modes[] =               { "1/6 Ev","1/3 Ev","1/2 Ev", "2/3 Ev","5/6 Ev","1 Ev","1 1/6Ev","1 1/3Ev","1 1/2Ev", "1 2/3Ev","1 5/6Ev","2 Ev","2 1/6Ev","2 1/3Ev","2 1/2Ev", "2 2/3Ev","2 5/6Ev","3 Ev","3 1/6Ev","3 1/3Ev","3 1/2Ev", "3 2/3Ev","3 5/6Ev","4 Ev"};
1163#if CAM_QUALITY_OVERRIDE
1164static const char* gui_fast_image_quality_modes[] =         { "Sup.Fine", "Fine", "Normal", "Off" };
1165#endif
1166
1167static CMenuItem tv_override_evstep[2] = {
1168    MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_VALUE,  MENUITEM_ENUM,            gui_tv_override_value_enum,         0 ),
1169    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1170};
1171
1172#ifdef CAM_EXT_TV_RANGE
1173static CMenuItem tv_override_long_exp[2] = {
1174    MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_LONG_EXP,  MENUITEM_ENUM|MENUITEM_HHMMSS, gui_hhmss_enum,             &conf.tv_override_long_exp ),
1175    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1176};
1177#endif
1178
1179static CMenuItem tv_override_short_exp[2] = {
1180    MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_SHORT_EXP, MENUITEM_ENUM|MENUITEM_DECIMAL, gui_decimal_enum,          &conf.tv_override_short_exp ),
1181    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1182};
1183
1184static CMenuItem iso_override_items[2] = {
1185    MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_override_value,           MENU_MINMAX(0, 10000) ),
1186    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.iso_override_koef,            0),
1187};
1188
1189static CMenuItem fast_ev_switch[2] = {
1190    MENU_ENUM2  (0, 0,                                                      &conf.fast_ev_step,                 gui_fast_ev_step_modes ),
1191    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.fast_ev,                      0 ),
1192};
1193
1194static CMenuItem manual_flash[2] = {
1195    MENU_ENUM2  (0, 0,                                                      &conf.flash_video_override_power,   gui_flash_power_modes ),
1196    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.flash_manual_override,        0 ),
1197};
1198
1199#if CAM_HAS_IRIS_DIAPHRAGM
1200static CMenuItem av_override_items[2] = {
1201    MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_av_override_enum,               0 ),
1202    MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.av_override_enabled,          0 ),
1203};
1204#endif
1205
1206#if CAM_CAN_SD_OVERRIDE
1207static CMenuItem sd_override_items[2] = {
1208    MENU_ITEM   (0, 0,   MENUITEM_ENUM|MENUITEM_SD_INT,                     gui_subj_dist_override_value_enum,  MAX_DIST ),
1209    MENU_ITEM   (0, 0,   MENUITEM_ENUM,                                     gui_subj_dist_override_koef_enum,   0 ),
1210};
1211#endif
1212
1213static CMenuItem operation_submenu_items[] = {
1214    MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_DISABLE,           &conf.override_disable, gui_override_disable_modes ),
1215    MENU_ITEM   (0x5c,LANG_MENU_OVERRIDE_DISABLE_ALL,       MENUITEM_BOOL,          &conf.override_disable_all,         0 ),
1216    MENU_ITEM   (0x59,LANG_MENU_TV_ENUM_TYPE,               MENUITEM_ENUM,          gui_tv_enum_type_enum,              0 ),
1217    MENU_ITEM   (0x61,LANG_MENU_OVERRIDE_TV_VALUE,          MENUITEM_STATE_VAL_PAIR,&tv_override_evstep,                0 ),
1218#if CAM_HAS_IRIS_DIAPHRAGM
1219    MENU_ITEM   (0x62,LANG_MENU_OVERRIDE_AV_VALUE,          MENUITEM_STATE_VAL_PAIR,&av_override_items,                 0 ),
1220#endif
1221    MENU_ITEM   (0x74,LANG_MENU_OVERRIDE_ISO_VALUE,         MENUITEM_STATE_VAL_PAIR,&iso_override_items,                10 ),
1222#if CAM_CAN_SD_OVERRIDE
1223    MENU_ITEM   (0x5e,LANG_MENU_OVERRIDE_SUBJ_DIST_VALUE,   MENUITEM_STATE_VAL_PAIR,&sd_override_items,                 0 ),
1224#endif
1225    MENU_ITEM   (0x5c,LANG_MENU_MISC_FAST_EV,               MENUITEM_STATE_VAL_PAIR,&fast_ev_switch,                    0 ),
1226    MENU_ITEM   (0x5c, LANG_MENU_FLASH_MANUAL_OVERRIDE,     MENUITEM_STATE_VAL_PAIR,&manual_flash,                      0 ),
1227#if CAM_HAS_VIDEO_BUTTON
1228    MENU_ITEM   (0x5c, LANG_MENU_FLASH_VIDEO_OVERRIDE,      MENUITEM_BOOL,          &conf.flash_video_override,         0 ),
1229#endif
1230#if CAM_REAR_CURTAIN
1231    MENU_ITEM   (0x5c, LANG_MENU_REAR_CURTAIN,              MENUITEM_BOOL,          &conf.flash_sync_curtain,           0 ),
1232#endif
1233#if CAM_HAS_ND_FILTER
1234    MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_ND_FILTER,         &conf.nd_filter_state,  gui_nd_filter_state_modes ),
1235#endif
1236#if ZOOM_OVERRIDE
1237    MENU_ITEM   (0x5c,LANG_MENU_OVERRIDE_ZOOM,              MENUITEM_BOOL,          &conf.zoom_override,                0 ),
1238    MENU_ITEM   (0x5f,LANG_MENU_OVERRIDE_ZOOM_VALUE,        MENUITEM_ENUM,          gui_zoom_override_enum,             0 ),
1239    MENU_ITEM   (0x5c,LANG_MENU_CLEAR_ZOOM_OVERRIDE_VALUES, MENUITEM_BOOL,          &conf.clear_zoom_override,          0 ),
1240#endif
1241#if CAM_QUALITY_OVERRIDE
1242    MENU_ENUM2  (0x5c,LANG_MENU_MISC_IMAGE_QUALITY,         &conf.fast_image_quality, gui_fast_image_quality_modes ),
1243#endif
1244    MENU_ITEM   (0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,      MENUITEM_SUBMENU,       &bracketing_in_continuous_submenu,  0 ),
1245    MENU_ITEM   (0x2d,LANG_MENU_AUTOISO,                    MENUITEM_SUBMENU,       &autoiso_submenu,                   0 ),
1246#ifdef OPT_CURVES
1247    MENU_ITEM   (0x85,LANG_MENU_CURVE_PARAM,                MENUITEM_SUBMENU,       &curve_submenu,                     0 ),
1248#endif
1249    MENU_ITEM   (0x5b,LANG_MENU_CLEAR_OVERRIDE_VALUES,      MENUITEM_BOOL,          &conf.clear_override,               0 ),
1250    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                  0 ),
1251    {0}
1252};
1253
1254static CMenu operation_submenu = {0x21,LANG_MENU_OPERATION_PARAM_TITLE, NULL, operation_submenu_items };
1255
1256void set_tv_override_menu()
1257{
1258    CMenuItem *mi = find_mnu(&operation_submenu,LANG_MENU_OVERRIDE_TV_VALUE);
1259    switch (conf.tv_enum_type)
1260    {
1261    case 0:     // Ev Step
1262        mi->value = (int*)(&tv_override_evstep);
1263        mi->arg = 1;
1264        break;
1265    case 1:     // Short exposure
1266        mi->value = (int*)(&tv_override_short_exp);
1267        mi->arg = 100;
1268        break;
1269#ifdef CAM_EXT_TV_RANGE
1270    case 2:     // Long exposure
1271        mi->value = (int*)(&tv_override_long_exp);
1272        mi->arg = 1;
1273        break;
1274#endif
1275    }
1276}
1277
1278//-------------------------------------------------------------------
1279
1280#ifdef OPT_EDGEOVERLAY
1281
1282static void gui_load_edge_selected( const char* fn )
1283{
1284    if (fn)
1285        libedgeovr->load_edge_overlay(fn);
1286}
1287
1288static void gui_menuproc_edge_save(int arg)
1289{
1290    libedgeovr->save_edge_overlay();
1291}
1292
1293static void gui_menuproc_edge_load(int arg)
1294{
1295    libfselect->file_select(LANG_MENU_EDGE_LOAD, EDGE_SAVE_DIR, EDGE_SAVE_DIR, gui_load_edge_selected);
1296}
1297
1298static const char* gui_edge_pano_modes[] =                  { "Off", "Right", "Down", "Left", "Up", "Free" };
1299static CMenuItem edge_overlay_submenu_items[] = {
1300    MENU_ITEM   (0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE,        MENUITEM_BOOL,          &conf.edge_overlay_enable,  0 ),
1301    MENU_ITEM   (0x5c,LANG_MENU_EDGE_FILTER,                MENUITEM_BOOL,          &conf.edge_overlay_filter,  0 ),
1302    MENU_ENUM2  (0x5f,LANG_MENU_EDGE_PANO,                  &conf.edge_overlay_pano, gui_edge_pano_modes ),
1303    MENU_ITEM   (0x5e,LANG_MENU_EDGE_PANO_OVERLAP,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_pano_overlap, MENU_MINMAX(0, 100) ),
1304    MENU_ITEM   (0x5c,LANG_MENU_EDGE_SHOW,                  MENUITEM_BOOL,          &conf.edge_overlay_show,    0 ),
1305    MENU_ITEM   (0x5e,LANG_MENU_EDGE_OVERLAY_TRESH,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255) ),
1306    MENU_ITEM   (0x5c,LANG_MENU_EDGE_PLAY,                  MENUITEM_BOOL,          &conf.edge_overlay_play,    0 ), //does not work on cams like s-series, which dont have a real "hardware" play/rec switch, need a workaround, probably another button
1307    MENU_ITEM   (0x33,LANG_MENU_EDGE_SAVE,                  MENUITEM_PROC,          gui_menuproc_edge_save,     0 ),
1308    MENU_ITEM   (0x5c,LANG_MENU_EDGE_ZOOM,                  MENUITEM_BOOL,          &conf.edge_overlay_zoom,    0 ),
1309    MENU_ITEM   (0x33,LANG_MENU_EDGE_LOAD,                  MENUITEM_PROC,          gui_menuproc_edge_load,     0 ),
1310    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                          0 ),
1311    {0}
1312};
1313
1314static CMenu edge_overlay_submenu = {0x7f,LANG_MENU_EDGE_OVERLAY_TITLE, NULL, edge_overlay_submenu_items };
1315
1316#endif
1317
1318//-------------------------------------------------------------------
1319
1320static void gui_grid_lines_load_selected(const char *fn)
1321{
1322    if (fn)
1323        libgrids->grid_lines_load(fn);
1324}
1325
1326static void gui_grid_lines_load(int arg)
1327{
1328    libfselect->file_select(LANG_STR_SELECT_GRID_FILE, conf.grid_lines_file, "A/CHDK/GRIDS", gui_grid_lines_load_selected);
1329}
1330
1331static CMenuItem grid_submenu_items[] = {
1332    MENU_ITEM(0x2f,LANG_MENU_SHOW_GRID,         MENUITEM_BOOL,          &conf.show_grid_lines, 0 ),
1333    MENU_ITEM(0x35,LANG_MENU_GRID_LOAD,         MENUITEM_PROC,          gui_grid_lines_load, 0 ),
1334    MENU_ITEM(0x0,LANG_MENU_GRID_CURRENT,       MENUITEM_SEPARATOR, 0, 0 ),
1335    MENU_ITEM(0x0,(int)conf.grid_title,         MENUITEM_TEXT,      0, 0 ),
1336    MENU_ITEM(0x0,(int)"",                      MENUITEM_SEPARATOR, 0, 0 ),
1337    MENU_ITEM(0x5c,LANG_MENU_GRID_FORCE_COLOR,  MENUITEM_BOOL,      &conf.grid_force_color, 0 ),
1338    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_LINE,   MENUITEM_COLOR_FG,  &conf.grid_color, 0 ),
1339    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_FILL,   MENUITEM_COLOR_BG,  &conf.grid_color, 0 ),
1340    MENU_ITEM(0x51,LANG_MENU_BACK,              MENUITEM_UP, 0, 0 ),
1341    {0}
1342};
1343
1344static CMenu grid_submenu = {0x2f,LANG_MENU_GRID_TITLE, NULL, grid_submenu_items };
1345
1346//-------------------------------------------------------------------
1347
1348static void gui_menu_run_palette(int arg)
1349{
1350    libpalette->show_palette(PALETTE_MODE_DEFAULT, 0, NULL);
1351}
1352
1353static CMenuItem visual_submenu_items[] = {
1354    MENU_ITEM(0x65,LANG_MENU_MISC_PALETTE,            MENUITEM_PROC,      gui_menu_run_palette, 0 ),
1355    MENU_ITEM(0x0,LANG_MENU_VIS_COLORS,               MENUITEM_SEPARATOR, 0, 0 ),
1356    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_TEXT,            MENUITEM_COLOR_FG,  &conf.osd_color, 0 ),
1357    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_BKG,             MENUITEM_COLOR_BG,  &conf.osd_color, 0 ),
1358    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING,         MENUITEM_COLOR_FG,  &conf.osd_color_warn, 0 ),
1359    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_warn, 0 ),
1360#ifdef OPT_EDGEOVERLAY
1361    MENU_ITEM(0x65,LANG_MENU_EDGE_OVERLAY_COLOR,      MENUITEM_COLOR_FG,  &conf.edge_overlay_color,   0 ),
1362#endif
1363    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO,               MENUITEM_COLOR_FG,  &conf.histo_color, 0 ),
1364    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BKG,           MENUITEM_COLOR_BG,  &conf.histo_color, 0 ),
1365    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BORDER,        MENUITEM_COLOR_FG,  &conf.histo_color2, 0 ),
1366    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_MARKERS,       MENUITEM_COLOR_BG,  &conf.histo_color2, 0 ),
1367    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_UNDER,         MENUITEM_COLOR_BG,  &conf.zebra_color, 0 ),
1368    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_OVER,          MENUITEM_COLOR_FG,  &conf.zebra_color, 0 ),
1369    //MENU_ITEM(0x65,LANG_MENU_VIS_BATT_ICON,           MENUITEM_COLOR_FG,  &conf.batt_icon_color, 0 ),
1370    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON,          MENUITEM_COLOR_FG,  &conf.space_color, 0 ),
1371    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON_BKG,      MENUITEM_COLOR_BG,  &conf.space_color, 0 ),
1372    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TEXT,           MENUITEM_COLOR_FG,  &conf.menu_color, 0 ),
1373    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_BKG,            MENUITEM_COLOR_BG,  &conf.menu_color, 0 ),
1374    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_TEXT,     MENUITEM_COLOR_FG,  &conf.menu_title_color, 0 ),
1375    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_BKG,      MENUITEM_COLOR_BG,  &conf.menu_title_color, 0 ),
1376    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_cursor_color, 0 ),
1377    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_BKG,     MENUITEM_COLOR_BG,  &conf.menu_cursor_color, 0 ),
1378    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_symbol_color, 0 ),
1379    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_BKG,     MENUITEM_COLOR_BG,  &conf.menu_symbol_color, 0 ),
1380    MENU_ITEM(0x65,LANG_MENU_VIS_READER_TEXT,         MENUITEM_COLOR_FG,  &conf.reader_color, 0 ),
1381    MENU_ITEM(0x65,LANG_MENU_VIS_READER_BKG,          MENUITEM_COLOR_BG,  &conf.reader_color, 0 ),
1382    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE,         MENUITEM_COLOR_FG,  &conf.osd_color_override, 0 ),
1383    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_override, 0 ),
1384    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1385    {0}
1386};
1387
1388static CMenu visual_submenu = {0x28,LANG_MENU_VIS_TITLE, NULL, visual_submenu_items };
1389
1390//-------------------------------------------------------------------
1391
1392static CMenuItem raw_state_submenu_items[] = {
1393    MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_RAW_STATE,         MENUITEM_BOOL,      &conf.show_raw_state,       0 ),
1394    MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_REMAINING_RAW,     MENUITEM_BOOL,      &conf.show_remaining_raw,   0 ),
1395    MENU_ITEM   (0x60,LANG_MENU_OSD_RAW_TRESHOLD,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.remaining_raw_treshold,   MENU_MINMAX(0, 200) ),
1396    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1397    {0}
1398};
1399
1400static CMenu raw_state_submenu = {0x24,LANG_MENU_OSD_RAW_STATE_PARAMS_TITLE, NULL, raw_state_submenu_items };
1401
1402//-------------------------------------------------------------------
1403
1404#ifdef  CAM_TOUCHSCREEN_UI
1405
1406static const char* gui_touchscreen_disable_modes[]=         { "Enable", "Disable" };
1407
1408static CMenuItem touchscreen_submenu_items[] = {
1409    MENU_ENUM2  (0x5f,LANG_MENU_TS_VIDEO_AE_DISABLE,        &conf.touchscreen_disable_video_controls,    gui_touchscreen_disable_modes ),
1410    MENU_ENUM2  (0x5f,LANG_MENU_TS_ALT_SHORTCUTS_DISABLE,   &conf.touchscreen_disable_shortcut_controls, gui_touchscreen_disable_modes ),
1411    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0, 0 ),
1412    {0}
1413};
1414
1415static CMenu touchscreen_submenu = {0x28,LANG_MENU_TOUCHSCREEN_VALUES, NULL, touchscreen_submenu_items };
1416
1417#endif
1418
1419//-------------------------------------------------------------------
1420
1421#ifdef CAM_HAS_CMOS
1422    static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CMOS", "Battery", "all" };
1423#else
1424    static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CCD", "Battery", "all" };
1425#endif
1426static const char* gui_hide_osd_modes[] =                   { "Don't", "In Playback", "On Disp Press", "Both" };
1427static const char* gui_show_usb_info_modes[] =              { "Off", "Icon", "Text" };
1428
1429static CMenuItem osd_submenu_items[] = {
1430    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW,              MENUITEM_BOOL,          &conf.show_osd, 0 ),
1431    MENU_ENUM2(0x5c,LANG_MENU_OSD_HIDE_PLAYBACK,                            &conf.hide_osd, gui_hide_osd_modes ),
1432    MENU_ITEM(0x5f,LANG_MENU_OSD_SHOW_STATES,       MENUITEM_BOOL,          &conf.show_state, 0 ),
1433    MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_TEMP,                                &conf.show_temp, gui_temp_mode_modes ),
1434    MENU_ITEM(0x59,LANG_MENU_OSD_TEMP_FAHRENHEIT,   MENUITEM_BOOL,          &conf.temperature_unit, 0 ),
1435    MENU_ENUM2(0x71,LANG_MENU_USB_SHOW_INFO,                                &conf.usb_info_enable, gui_show_usb_info_modes ),
1436    MENU_ITEM(0x22,LANG_MENU_OSD_VALUES,                MENUITEM_SUBMENU,       &values_submenu, 0 ),
1437    MENU_ITEM(0x31,LANG_MENU_OSD_DOF_CALC,          MENUITEM_SUBMENU,       &dof_submenu, 0 ),
1438    MENU_ITEM(0x24,LANG_MENU_OSD_RAW_STATE_PARAMS,  MENUITEM_SUBMENU,       &raw_state_submenu, 0 ),
1439    MENU_ITEM(0x32,LANG_MENU_OSD_BATT_PARAMS,       MENUITEM_SUBMENU,       &battery_submenu, 0 ),
1440    MENU_ITEM(0x33,LANG_MENU_OSD_SPACE_PARAMS,      MENUITEM_SUBMENU,       &space_submenu, 0 ),
1441    MENU_ITEM(0x34,LANG_MENU_OSD_CLOCK_PARAMS,          MENUITEM_SUBMENU,       &clock_submenu, 0 ),
1442    MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_IN_REVIEW,    MENUITEM_BOOL,          &conf.show_osd_in_review, 0 ),
1443#ifdef  CAM_TOUCHSCREEN_UI
1444    MENU_ITEM   (0x22,LANG_MENU_TOUCHSCREEN_VALUES,         MENUITEM_SUBMENU,   &touchscreen_submenu,       0 ),
1445#endif
1446    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0,                                 0 ),
1447    {0}
1448};
1449
1450static CMenu osd_submenu = {0x22,LANG_MENU_OSD_TITLE, NULL, osd_submenu_items };
1451
1452//-------------------------------------------------------------------
1453
1454static const char* gui_histo_show_modes[] =                 { "Don't", "Always", "Shoot" };
1455static const char* gui_histo_view_modes[]={ "RGB", "Y", "RGB Y",  "R G B", "RGB all", "Y all", "Blend", "Blend Y"};
1456static const char* gui_histo_transform_modes[]={ "Linear", "Log" };
1457
1458static CMenuItem histo_submenu_items[] = {
1459    MENU_ENUM2(0x5f,LANG_MENU_HISTO_SHOW,             &conf.show_histo,     gui_histo_show_modes ),
1460    MENU_ENUM2(0x6f,LANG_MENU_HISTO_LAYOUT,           &conf.histo_layout,   gui_histo_view_modes ),
1461    MENU_ENUM2(0x5f,LANG_MENU_HISTO_MODE,             &conf.histo_mode,     gui_histo_transform_modes ),
1462    MENU_ITEM(0x5c,LANG_MENU_HISTO_EXP,               MENUITEM_BOOL,       &conf.show_overexp, 0 ),
1463    MENU_ITEM(0x70,LANG_MENU_HISTO_IGNORE_PEAKS,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.histo_ignore_boundary,   MENU_MINMAX(0, 32) ),
1464    MENU_ITEM(0x5c,LANG_MENU_HISTO_MAGNIFY,           MENUITEM_BOOL,       &conf.histo_auto_ajust, 0 ),
1465    MENU_ITEM(0x5c,LANG_MENU_HISTO_SHOW_EV_GRID,      MENUITEM_BOOL,       &conf.histo_show_ev_grid, 0 ),
1466    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1467    {0}
1468};
1469
1470static CMenu histo_submenu = {0x25,LANG_MENU_HISTO_TITLE, NULL, histo_submenu_items };
1471
1472//-------------------------------------------------------------------
1473
1474static CMenuItem raw_exceptions_submenu_items[] = {
1475#if defined CAM_HAS_VIDEO_BUTTON
1476    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_VIDEO,          MENUITEM_BOOL,      &conf.save_raw_in_video,        0 ),
1477#endif
1478#if defined(CAM_HAS_SPORTS_MODE)
1479    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_SPORTS,         MENUITEM_BOOL,      &conf.save_raw_in_sports,       0 ),
1480#endif
1481    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_BURST,          MENUITEM_BOOL,      &conf.save_raw_in_burst,        0 ),
1482    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_TIMER,          MENUITEM_BOOL,      &conf.save_raw_in_timer,        0 ),
1483    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EDGEOVERLAY,    MENUITEM_BOOL,      &conf.save_raw_in_edgeoverlay,  0 ),
1484    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_AUTO,           MENUITEM_BOOL,      &conf.save_raw_in_auto,         0 ),
1485#if CAM_BRACKETING
1486    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EV_BRACKETING,  MENUITEM_BOOL,      &conf.save_raw_in_ev_bracketing, 0 ),
1487#endif
1488    MENU_ITEM   (0x5c,LANG_MENU_RAW_WARN,                   MENUITEM_BOOL,      &conf.raw_exceptions_warn,      0 ),
1489    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                              0 ),
1490    {0}
1491};
1492
1493static CMenu raw_exceptions_submenu = {0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS_TITLE, NULL, raw_exceptions_submenu_items };
1494
1495//-------------------------------------------------------------------
1496
1497static void cb_change_dng()
1498{
1499     int old=conf.dng_version;
1500     conf_change_dng();
1501     if ((old==1) && (conf.dng_version==0)) gui_mbox_init(LANG_ERROR, LANG_CANNOT_OPEN_BADPIXEL_FILE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1502}
1503   
1504static const char* gui_dng_version(int change, int arg)
1505{
1506    static const char* modes[]={ "1.3", "1.1" };
1507
1508    gui_enum_value_change(&conf.dng_version,change,sizeof(modes)/sizeof(modes[0]));
1509    cb_change_dng();
1510
1511    return modes[conf.dng_version];
1512}
1513
1514static void gui_menuproc_badpixel_create(int arg)
1515{
1516    libdng->create_badpixel_bin();
1517}
1518
1519static void raw_fselect_cb(const char * filename)
1520{
1521    raw_prepare_develop(filename, 1);
1522}
1523
1524static void gui_raw_develop(int arg)
1525{
1526    libfselect->file_select(LANG_RAW_DEVELOP_SELECT_FILE, "A/DCIM", "A", raw_fselect_cb);
1527}
1528   
1529static const char* gui_bad_pixel_enum(int change, int arg)
1530{
1531    int modes[]={LANG_MENU_BAD_PIXEL_OFF, LANG_MENU_BAD_PIXEL_INTERPOLATION, LANG_MENU_BAD_PIXEL_RAW_CONVERTER};
1532   
1533    return lang_str((int)gui_change_simple_enum(&conf.bad_pixel_removal,change,(const char**)modes,sizeof(modes)/sizeof(modes[0])));
1534}
1535
1536#if defined (DNG_EXT_FROM)
1537extern void cb_change_dng_usb_ext();
1538#endif
1539
1540static const char* gui_raw_nr_modes[] =                     { "Auto", "Off", "On"};
1541
1542static CMenuItem raw_submenu_items[] = {
1543    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE,                   MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.save_raw, (int)cb_change_dng ),
1544    MENU_ITEM   (0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS,      MENUITEM_SUBMENU,   &raw_exceptions_submenu, 0 ),
1545    MENU_ENUM2  (0x5f,LANG_MENU_RAW_NOISE_REDUCTION,        &conf.raw_nr,       gui_raw_nr_modes ),
1546    MENU_ITEM   (0x5c,LANG_MENU_RAW_FIRST_ONLY,             MENUITEM_BOOL,      &conf.raw_save_first_only, 0 ),
1547    MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_DIR,            MENUITEM_BOOL,      &conf.raw_in_dir, 0 ),
1548    MENU_ENUM2a (0x5f,LANG_MENU_RAW_PREFIX,                 &conf.raw_prefix,   img_prefixes, NUM_IMG_PREFIXES ),
1549    MENU_ENUM2a (0x5f,LANG_MENU_RAW_EXTENSION,              &conf.raw_ext,      img_exts, NUM_IMG_EXTS ),
1550    MENU_ENUM2a (0x5f,LANG_MENU_SUB_PREFIX,                 &conf.sub_batch_prefix, img_prefixes, NUM_IMG_PREFIXES ),
1551    MENU_ENUM2a (0x5f,LANG_MENU_SUB_EXTENSION,              &conf.sub_batch_ext, img_exts, NUM_IMG_EXTS ),
1552//  MENU_ITEM   (0x60,LANG_MENU_SUB_IN_DARK_VALUE,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_in_dark_value, MENU_MINMAX(0, 1023) ),
1553//  MENU_ITEM   (0x60,LANG_MENU_SUB_OUT_DARK_VALUE,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_out_dark_value, MENU_MINMAX(0, 1023) ),
1554    MENU_ITEM   (0x2a,LANG_MENU_RAW_DEVELOP,                MENUITEM_PROC,      gui_raw_develop, 0 ),
1555    MENU_ITEM   (0x5c,LANG_MENU_BAD_PIXEL_REMOVAL,          MENUITEM_ENUM,      gui_bad_pixel_enum, 0 ),
1556    MENU_ITEM   (0x5c,LANG_MENU_RAW_CACHED,                 MENUITEM_BOOL,      &conf.raw_cache,            0 ),
1557#ifdef OPT_DEBUGGING
1558    MENU_ITEM   (0x5c,LANG_MENU_RAW_TIMER,                  MENUITEM_BOOL,      &conf.raw_timer,            0 ),
1559#endif
1560    MENU_ITEM   (0x0 ,(int)"DNG",                           MENUITEM_SEPARATOR, 0,                                                      0 ),
1561    MENU_ITEM   (0x5c,LANG_MENU_DNG_FORMAT,                 MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_raw , (int)cb_change_dng ),
1562    MENU_ITEM   (0x5c,LANG_MENU_RAW_DNG_EXT,                MENUITEM_BOOL,      &conf.raw_dng_ext, 0 ),
1563    MENU_ITEM   (0x5f,LANG_MENU_DNG_VERSION,                MENUITEM_ENUM,      gui_dng_version, 0),
1564    MENU_ITEM   (0x2a,LANG_MENU_BADPIXEL_CREATE,            MENUITEM_PROC,      gui_menuproc_badpixel_create, 0 ),
1565#if defined (DNG_EXT_FROM)
1566    MENU_ITEM   (0x71,LANG_MENU_DNG_VIA_USB,                MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_usb_ext , (int)cb_change_dng_usb_ext ),
1567#endif
1568    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1569    {0}
1570};
1571
1572static CMenu raw_submenu = {0x24,LANG_MENU_RAW_TITLE, NULL, raw_submenu_items };
1573
1574//-------------------------------------------------------------------
1575
1576void cb_zebra_restore_screen()
1577{
1578    if (!conf.zebra_restore_screen)
1579        conf.zebra_restore_osd = 0;
1580}
1581
1582void cb_zebra_restore_osd()
1583{
1584    if (conf.zebra_restore_osd)
1585        conf.zebra_restore_screen = 1;
1586}
1587
1588static const char* gui_zebra_mode_modes[] = { "Blink 1", "Blink 2", "Blink 3", "Solid", "Zebra 1", "Zebra 2" };
1589static const char* gui_zebra_draw_osd_modes[] = { "Nothing", "Histo", "OSD" };
1590
1591static CMenuItem zebra_submenu_items[] = {
1592    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_DRAW,              MENUITEM_BOOL,                            &conf.zebra_draw, 0 ),
1593    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_MODE,             &conf.zebra_mode, gui_zebra_mode_modes ),
1594    MENU_ITEM(0x58,LANG_MENU_ZEBRA_UNDER,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_under,   MENU_MINMAX(0, 32) ),
1595    MENU_ITEM(0x57,LANG_MENU_ZEBRA_OVER,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_over,    MENU_MINMAX(0, 32) ),
1596    MENU_ITEM(0x28,LANG_MENU_ZEBRA_RESTORE_SCREEN,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_screen,     cb_zebra_restore_screen ),
1597    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_RESTORE_OSD,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_osd,        cb_zebra_restore_osd ),
1598    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_DRAW_OVER,        &conf.zebra_draw_osd, gui_zebra_draw_osd_modes ),
1599    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_MULTICHANNEL,      MENUITEM_BOOL,                            &conf.zebra_multichannel, 0 ),
1600    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1601    {0}
1602};
1603
1604static CMenu zebra_submenu = {0x26,LANG_MENU_ZEBRA_TITLE, NULL, zebra_submenu_items };
1605
1606//-------------------------------------------------------------------
1607
1608static void gui_draw_lang_selected(const char *fn)
1609{
1610    if (fn) {
1611        strcpy(conf.lang_file, fn);
1612        lang_load_from_file(conf.lang_file);
1613        gui_menu_init(NULL);
1614    }
1615}
1616
1617static void gui_draw_load_lang(int arg)
1618{
1619    libfselect->file_select(LANG_STR_SELECT_LANG_FILE, conf.lang_file, "A/CHDK/LANG", gui_draw_lang_selected);
1620}
1621
1622static const char* gui_font_enum(int change, int arg)
1623{
1624    static const char* fonts[]={ "Win1250", "Win1251", "Win1252", "Win1253", "Win1254", "Win1257"};
1625
1626    gui_enum_value_change(&conf.font_cp,change,sizeof(fonts)/sizeof(fonts[0]));
1627
1628    if (change != 0) {
1629        font_set(conf.font_cp);
1630        rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1631        gui_menu_init(NULL);
1632    }
1633
1634    return fonts[conf.font_cp];
1635}
1636
1637static void gui_draw_menu_rbf_selected(const char *fn)
1638{
1639    if (fn) {
1640        strcpy(conf.menu_rbf_file, fn);
1641        rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1642        gui_menu_init(NULL);
1643    }
1644}
1645
1646static void gui_draw_load_menu_rbf(int arg)
1647{
1648    libfselect->file_select(LANG_STR_SELECT_FONT_FILE, conf.menu_rbf_file, "A/CHDK/FONTS", gui_draw_menu_rbf_selected);
1649}
1650
1651static void gui_draw_symbol_rbf_selected(const char *fn)
1652{
1653    if (fn) {
1654        strcpy(conf.menu_symbol_rbf_file, fn);
1655        if(!rbf_load_symbol(conf.menu_symbol_rbf_file)) conf.menu_symbol_enable=0;              //AKA
1656        gui_menu_init(NULL);
1657    }
1658}
1659
1660static void gui_draw_load_symbol_rbf(int arg)
1661{
1662    libfselect->file_select(LANG_STR_SELECT_SYMBOL_FILE, conf.menu_symbol_rbf_file, "A/CHDK/SYMBOLS", gui_draw_symbol_rbf_selected);
1663}
1664
1665static void gui_menuproc_reset_files(int arg)
1666{
1667    conf.lang_file[0] = 0;
1668    strcpy(conf.menu_symbol_rbf_file,DEFAULT_SYMBOL_FILE);
1669    conf.menu_rbf_file[0] = 0;
1670    conf_save();
1671    gui_mbox_init(LANG_INFORMATION, LANG_MENU_RESTART_CAMERA, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1672}
1673
1674static const char* gui_text_box_charmap[] = { "Default", "German", "Russian" };
1675
1676static CMenuItem menu_font_submenu_items[] = {
1677    MENU_ITEM(0x35,LANG_MENU_VIS_LANG,                MENUITEM_PROC,      gui_draw_load_lang, 0 ),
1678    MENU_ITEM(0x5f,LANG_MENU_VIS_OSD_FONT,            MENUITEM_ENUM,      gui_font_enum, &conf.font_cp ),
1679    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_FONT,           MENUITEM_PROC,      gui_draw_load_menu_rbf, 0 ),
1680    MENU_ITEM(0x64,LANG_MENU_VIS_SYMBOL,              MENUITEM_BOOL,      &conf.menu_symbol_enable, 0 ),
1681    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_SYMBOL_FONT,    MENUITEM_PROC,      gui_draw_load_symbol_rbf, 0 ),
1682    MENU_ENUM2(0x5f,LANG_MENU_VIS_CHARMAP,            &conf.tbox_char_map, gui_text_box_charmap ),
1683    MENU_ITEM(0x80,LANG_MENU_RESET_FILES,             MENUITEM_PROC,      gui_menuproc_reset_files, 0 ),
1684    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1685    {0}
1686};
1687
1688static CMenu menu_font_submenu = {0x28,LANG_MENU_FONT_SETTINGS, NULL, menu_font_submenu_items };
1689
1690//-------------------------------------------------------------------
1691
1692static const char* gui_user_menu_show_enum(int change, int arg)
1693{
1694    static const char* modes[]={ "Off", "On", "On Direct" };
1695
1696    void set_usermenu_state();
1697    set_usermenu_state();
1698
1699    return gui_change_simple_enum(&conf.user_menu_enable,change,modes,sizeof(modes)/sizeof(modes[0]));
1700}
1701
1702static CMenuItem menu_settings_submenu_items[] = {
1703    MENU_ITEM(0x5f,LANG_MENU_USER_MENU_ENABLE,          MENUITEM_ENUM,          gui_user_menu_show_enum, 0 ),
1704    MENU_ITEM(0x5c,LANG_MENU_USER_MENU_AS_ROOT,     MENUITEM_BOOL,          &conf.user_menu_as_root, 0 ),
1705    MENU_ITEM(0x72,LANG_MENU_USER_MENU_EDIT,        MENUITEM_PROC,          module_run, "useredit.flt" ),
1706    MENU_ITEM(0x81,LANG_MENU_VIS_MENU_CENTER,       MENUITEM_BOOL,              &conf.menu_center, 0 ),
1707    MENU_ITEM(0x81,LANG_MENU_SELECT_FIRST_ENTRY,    MENUITEM_BOOL,              &conf.menu_select_first_entry, 0 ),
1708    MENU_ITEM(0x5c,LANG_MENU_SHOW_ALT_HELP,         MENUITEM_BOOL,          &conf.show_alt_helper, 0 ),
1709    MENU_ITEM(0x58,LANG_MENU_SHOW_ALT_HELP_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.show_alt_helper_delay, MENU_MINMAX(0, 10) ),
1710    MENU_ITEM(0x28,LANG_MENU_FONT_SETTINGS,         MENUITEM_SUBMENU,       &menu_font_submenu, 0 ),
1711    MENU_ITEM(0x51,LANG_MENU_BACK,                  MENUITEM_UP, 0, 0 ),
1712    {0}
1713};
1714
1715static CMenu menu_settings_submenu = {0x28,LANG_MENU_MENU_SETTINGS, NULL, menu_settings_submenu_items };
1716
1717//-------------------------------------------------------------------
1718
1719#if CAM_ADJUSTABLE_ALT_BUTTON
1720
1721static const char* gui_alt_mode_button_enum(int change, int arg)
1722{
1723#if defined(CAM_ALT_BUTTON_NAMES) && defined(CAM_ALT_BUTTON_OPTIONS)
1724    static const char* names[] = CAM_ALT_BUTTON_NAMES;
1725    static const int keys[] = CAM_ALT_BUTTON_OPTIONS;
1726#else
1727#error Make sure CAM_ALT_BUTTON_NAMES and CAM_ALT_BUTTON_OPTIONS are defined in platform_camera.h
1728#endif
1729    int i;
1730
1731    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1732        if (conf.alt_mode_button==keys[i]) {
1733            break;
1734        }
1735    }
1736
1737    i+=change;
1738    if (i<0)
1739        i=(sizeof(names)/sizeof(names[0]))-1;
1740    else if (i>=(sizeof(names)/sizeof(names[0])))
1741        i=0;
1742
1743    conf.alt_mode_button = keys[i];
1744    kbd_set_alt_mode_key_mask(conf.alt_mode_button);
1745    return names[i];
1746}
1747#endif
1748
1749#if CAM_OPTIONAL_EXTRA_BUTTON
1750static const char* gui_extra_button_enum(int change, int arg)
1751{
1752#if defined(CAM_EXTRA_BUTTON_NAMES) && defined(CAM_EXTRA_BUTTON_OPTIONS)
1753    static const char* names[] = CAM_EXTRA_BUTTON_NAMES;
1754    static const int keys[] = CAM_EXTRA_BUTTON_OPTIONS;
1755#else
1756#error Make sure CAM_EXTRA_BUTTON_NAMES and CAM_EXTRA_BUTTON_OPTIONS are defined in platform_camera.h
1757#endif
1758    int i;
1759
1760    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1761        if (conf.extra_button==keys[i]) {
1762            break;
1763        }
1764    }
1765
1766    i+=change;
1767    if (i<0)
1768        i=(sizeof(names)/sizeof(names[0]))-1;
1769    else if (i>=(sizeof(names)/sizeof(names[0])))
1770        i=0;
1771
1772    conf.extra_button = keys[i];
1773    kbd_set_extra_button((short)conf.extra_button);
1774    return names[i];
1775}
1776#endif //CAM_OPTIONAL_EXTRA_BUTTON
1777
1778static const char* gui_alt_power_enum(int change, int arg)
1779{
1780// Script option is retained even if scripting is disabled, otherwise conf values will change
1781// Equivalent to ALT
1782    static const char* modes[]={ "Never", "Alt", "Script", "Always" };
1783
1784    gui_enum_value_change(&conf.alt_prevent_shutdown,change,sizeof(modes)/sizeof(modes[0]));
1785       
1786    return modes[conf.alt_prevent_shutdown];
1787}
1788
1789static void gui_menuproc_reset_selected(unsigned int btn)
1790{
1791    if (btn==MBOX_BTN_YES)
1792        conf_load_defaults();
1793}
1794
1795static void gui_menuproc_reset(int arg)
1796{
1797    gui_mbox_init(LANG_MSG_RESET_OPTIONS_TITLE,
1798                  LANG_MSG_RESET_OPTIONS_TEXT,
1799                  MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menuproc_reset_selected);
1800}
1801
1802static CMenuItem chdk_settings_menu_items[] = {
1803    MENU_ITEM   (0x22,LANG_MENU_MAIN_OSD_PARAM,             MENUITEM_SUBMENU,   &osd_submenu, 0 ),
1804    MENU_ITEM   (0x72,LANG_MENU_OSD_LAYOUT_EDITOR,          MENUITEM_PROC,      module_run, "_osd_le.flt" ),
1805    MENU_ITEM   (0x28,LANG_MENU_MAIN_VISUAL_PARAM,          MENUITEM_SUBMENU,   &visual_submenu, 0 ),
1806    MENU_ITEM   (0x28,LANG_MENU_MENU_SETTINGS,              MENUITEM_SUBMENU,   &menu_settings_submenu, 0 ),
1807    MENU_ITEM   (0x2f,LANG_MENU_OSD_GRID_PARAMS,            MENUITEM_SUBMENU,   &grid_submenu, 0 ),
1808#ifdef CAM_HAS_GPS
1809    MENU_ITEM   (0x2a,LANG_MENU_GPS,                        MENUITEM_SUBMENU,   &gps_submenu,           0 ),
1810#endif
1811#if CAM_REMOTE
1812    MENU_ITEM   (0x86,LANG_MENU_REMOTE_PARAM,               MENUITEM_SUBMENU,   &remote_submenu, 0 ),
1813#endif
1814    MENU_ITEM   (0x5c,LANG_MENU_MISC_ENABLE_SHORTCUTS,      MENUITEM_BOOL,      &conf.enable_shortcuts, 0 ),
1815    MENU_ITEM   (0x5c,LANG_MENU_MISC_SHOW_SPLASH,           MENUITEM_BOOL,      &conf.splash_show, 0 ),
1816    MENU_ITEM   (0x5c,LANG_MENU_MISC_START_SOUND,           MENUITEM_BOOL,      &conf.start_sound, 0 ),
1817#if CAM_USE_ZOOM_FOR_MF
1818    MENU_ITEM   (0x59,LANG_MENU_MISC_ZOOM_FOR_MF,           MENUITEM_BOOL,      &conf.use_zoom_mf, 0 ),
1819#endif
1820#if CAM_ADJUSTABLE_ALT_BUTTON
1821    MENU_ITEM   (0x22,LANG_MENU_MISC_ALT_BUTTON,            MENUITEM_ENUM,      gui_alt_mode_button_enum, 0 ),
1822#endif
1823#if CAM_OPTIONAL_EXTRA_BUTTON
1824    MENU_ITEM   (0x22,LANG_MENU_MISC_EXTRA_BUTTON,          MENUITEM_ENUM,      gui_extra_button_enum, 0 ),
1825#endif
1826#if defined(CAM_ZOOM_ASSIST_BUTTON_CONTROL)
1827    MENU_ITEM   (0x5c,LANG_MENU_MISC_ZOOM_ASSIST,           MENUITEM_BOOL,      &conf.zoom_assist_button_disable, 0 ),
1828#endif
1829    MENU_ITEM   (0x5d,LANG_MENU_MISC_DISABLE_LCD_OFF,       MENUITEM_ENUM,      gui_alt_power_enum, 0 ),
1830    MENU_ITEM   (0x2b,LANG_MENU_MAIN_RESET_OPTIONS,         MENUITEM_PROC,      gui_menuproc_reset, 0 ),
1831    MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0, 0 ),
1832    {0}
1833};
1834
1835CMenu chdk_settings_menu = {0x20,LANG_MENU_CHDK_SETTINGS, NULL, chdk_settings_menu_items };
1836
1837//-------------------------------------------------------------------
1838
1839extern CMenu script_submenu;
1840
1841static CMenuItem root_menu_items[] = {
1842    MENU_ITEM   (0x21,LANG_MENU_OPERATION_PARAM,            MENUITEM_SUBMENU,   &operation_submenu, 0 ),
1843    MENU_ITEM   (0x23,LANG_MENU_VIDEO_PARAM,                MENUITEM_SUBMENU,   &video_submenu,     0 ),
1844    MENU_ITEM   (0x24,LANG_MENU_MAIN_RAW_PARAM,             MENUITEM_SUBMENU,   &raw_submenu,       0 ),
1845#ifdef OPT_EDGEOVERLAY
1846    MENU_ITEM   (0x7f,LANG_MENU_EDGE_OVERLAY,               MENUITEM_SUBMENU,   &edge_overlay_submenu, 0 ),
1847#endif
1848    MENU_ITEM   (0x25,LANG_MENU_MAIN_HISTO_PARAM,           MENUITEM_SUBMENU,   &histo_submenu, 0 ),
1849    MENU_ITEM   (0x26,LANG_MENU_MAIN_ZEBRA_PARAM,           MENUITEM_SUBMENU,   &zebra_submenu,     0 ),
1850    MENU_ITEM   (0x27,LANG_MENU_MAIN_SCRIPT_PARAM,          MENUITEM_SUBMENU,   &script_submenu,    0 ),
1851    MENU_ITEM   (0x22,LANG_MENU_CHDK_SETTINGS,              MENUITEM_SUBMENU,   &chdk_settings_menu, 0 ),
1852    MENU_ITEM   (0x29,LANG_MENU_MAIN_MISC,                  MENUITEM_SUBMENU,   &misc_submenu,      0 ),
1853    MENU_ITEM   (0x2e,LANG_MENU_USER_MENU,                  MENUITEM_SUBMENU,   &user_submenu, 0 ),
1854    {0}
1855};
1856
1857CMenu root_menu = {0x20,LANG_MENU_MAIN_TITLE, NULL, root_menu_items };
1858
1859// Set visibility of User Menu in root menu based on user menu state
1860// Note this hack requires the User Menu entry to be the last one in the root_menu_items array above.
1861void set_usermenu_state()
1862{
1863    int i;
1864    for (i=0; root_menu_items[i].symbol != 0; i++)
1865    {
1866        if (root_menu_items[i].value == (int*)&user_submenu)
1867        {
1868            if (conf.user_menu_enable)
1869                root_menu_items[i].text = LANG_MENU_USER_MENU;  // Enable user menu option in root menu
1870            else
1871                root_menu_items[i].text = 0;                    // Disable user menu option in root menu
1872            return;
1873        }
1874    }
1875}
1876
1877//-------------------------------------------------------------------
1878
1879const char* gui_on_off_enum(int change, int *conf_val)
1880{
1881    static const char* modes[]={ "Off", "On"};
1882    return gui_change_simple_enum(conf_val,change,modes,sizeof(modes)/sizeof(modes[0]));
1883}
1884
1885#ifdef  CAM_TOUCHSCREEN_UI
1886
1887const char* gui_override_disable_enum(int change, int arg)
1888{
1889    return gui_change_simple_enum(&conf.override_disable,change,gui_override_disable_modes,sizeof(gui_override_disable_modes)/sizeof(gui_override_disable_modes[0]));
1890}
1891
1892const char* gui_nd_filter_state_enum(int change, int arg)
1893{
1894    return gui_change_simple_enum(&conf.nd_filter_state,change,gui_nd_filter_state_modes,sizeof(gui_nd_filter_state_modes)/sizeof(gui_nd_filter_state_modes[0]));
1895}
1896
1897const char* gui_histo_show_enum(int change, int arg)
1898{
1899    return gui_change_simple_enum(&conf.show_histo,change,gui_histo_show_modes,sizeof(gui_histo_show_modes)/sizeof(gui_histo_show_modes[0]));
1900}
1901
1902#endif
1903
1904//-------------------------------------------------------------------
1905static gui_handler *gui_mode=0; // current gui mode. pointer to gui_handler structure
1906
1907static int gui_osd_need_restore = 0;    // Set when screen needs to be erase and redrawn
1908static int gui_mode_need_redraw = 0;    // Set if current mode needs to redraw itself
1909static int gui_splash, gui_splash_mode;
1910
1911//-------------------------------------------------------------------
1912
1913void gui_set_need_restore()
1914{
1915    gui_osd_need_restore = 1;
1916}
1917
1918void gui_cancel_need_restore()
1919{
1920    gui_osd_need_restore = 0;
1921    gui_mode_need_redraw = 0;
1922}
1923
1924void gui_set_need_redraw()
1925{
1926    gui_mode_need_redraw = 1;
1927}
1928
1929//-------------------------------------------------------------------
1930void gui_init()
1931{
1932    set_tv_override_menu();
1933
1934    gui_set_mode(&defaultGuiHandler);
1935    if (conf.start_sound>0)
1936    {
1937        play_sound(4);
1938    }
1939    gui_splash = (conf.splash_show)?SPLASH_TIME:0;
1940    draw_init();
1941
1942    load_from_file( "A/CHDK/badpixel", make_pixel_list );
1943    load_from_file( "A/CHDK/badpixel.txt", make_pixel_list );
1944}
1945
1946//-------------------------------------------------------------------
1947gui_mode_t gui_get_mode() { return gui_mode->mode; }
1948
1949//-------------------------------------------------------------------
1950// Set new GUI mode, returns old mode
1951gui_handler* gui_set_mode(gui_handler *mode)
1952{
1953        if ( gui_mode == mode )
1954                return gui_mode;
1955       
1956#ifdef CAM_TOUCHSCREEN_UI
1957    if (((gui_mode->mode == GUI_MODE_NONE) != (mode->mode == GUI_MODE_NONE)) ||    // Change from GUI_MODE_NONE to any other or vice-versa
1958        ((gui_mode->mode > GUI_MODE_MENU)  != (mode->mode > GUI_MODE_MENU)))       // Switch in & out of menu mode
1959        redraw_buttons = 1;
1960#endif
1961
1962    set_usermenu_state();
1963
1964    gui_handler *old_mode = gui_mode;
1965    gui_mode = mode;
1966
1967    gui_osd_need_restore = 0;
1968
1969    // Flag for screen erase/redraw unless mode is marked not to (e.g. menu box popup)
1970    if (((gui_mode->flags & (GUI_MODE_FLAG_NODRAWRESTORE|GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) == 0) &&
1971        ((old_mode->flags & GUI_MODE_FLAG_NORESTORE_ON_SWITCH) == 0))
1972        gui_set_need_restore();
1973    // If old mode did not erase screen on exit then force current mode to redraw itself (e.g. exit menu popup back to file select)
1974    if ((old_mode->flags & (GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) != 0)
1975        gui_set_need_redraw();
1976
1977#ifdef CAM_DISP_ALT_TEXT
1978    if (gui_mode->mode == GUI_MODE_ALT)
1979        gui_reset_alt_helper();
1980#endif
1981
1982    return old_mode;
1983}
1984
1985//-------------------------------------------------------------------
1986#if defined(VER_CHDK)
1987#define LOGO_WIDTH  149
1988#define LOGO_HEIGHT 84
1989#else
1990#define LOGO_WIDTH  169
1991#define LOGO_HEIGHT 74
1992#endif
1993
1994static void gui_draw_splash(char* logo, int logo_size) {
1995    coord w, h, x, y;
1996    static const char *text[] = {
1997        "CHDK Version '" HDK_VERSION " " BUILD_NUMBER "-" BUILD_SVNREV "'" ,
1998        "Build: " __DATE__ " " __TIME__ ,
1999        "Camera: " PLATFORM " - " PLATFORMSUB };
2000    int i, l;
2001    color cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
2002
2003    gui_splash_mode = (mode_get()&MODE_MASK);
2004   
2005    h=sizeof(text)/sizeof(text[0])*FONT_HEIGHT+8;
2006    w=0;
2007    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2008        l=strlen(text[i]);
2009        if (l>w) w=l;
2010    }
2011    w=w*FONT_WIDTH+10;
2012
2013    x = (camera_screen.width-w)>>1; y = ((camera_screen.height-h)>>1) + 20;
2014    draw_filled_round_rect(x, y, x+w, y+h, MAKE_COLOR(COLOR_RED, COLOR_RED));
2015    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2016        draw_string(x+((w-strlen(text[i])*FONT_WIDTH)>>1), y+i*FONT_HEIGHT+4, text[i], cl);
2017    }
2018    if(logo){
2019      int pos;
2020      int mx=0;
2021      int my=0;
2022      int offset_x = (CAM_SCREEN_WIDTH-LOGO_WIDTH)>>1;
2023      int offset_y = ((CAM_SCREEN_HEIGHT-LOGO_HEIGHT)>>1) - 42;
2024      const color color_lookup[8] = {COLOR_BLACK,
2025                                    COLOR_SPLASH_RED/*0x2E redish*/,
2026                                    COLOR_RED,
2027                                    COLOR_GREY /*0x3D*/,
2028                                    COLOR_SPLASH_GREY /*0x1F*/,
2029                                    COLOR_SPLASH_PINK /*0x21 pinkish*/,
2030                                    COLOR_TRANSPARENT /*0x00*/,
2031                                    COLOR_WHITE /*0x11*/};
2032      for(pos=0; pos<logo_size; pos++){
2033          char data = logo[pos];
2034          color c = color_lookup[(data>>5) & 0x07];
2035          for(i=0; i<(data&0x1F)+1; i++){
2036              if (c!=0x00){
2037                  draw_pixel(offset_x+mx,offset_y+my,c);
2038              }
2039              if (mx==LOGO_WIDTH){
2040                  mx=0;
2041                  my++;
2042              }else{
2043                  mx++;
2044              }     
2045          }
2046      }
2047    }
2048}
2049
2050static void gui_handle_splash(void) {
2051    static char *logo = NULL;
2052    static int logo_size;
2053    if (gui_splash) {
2054        static int need_logo=1; // don't use logo ptr, since we don't want to keep re-trying
2055        if(need_logo) {
2056#if defined(VER_CHDK)
2057            const char *logo_name="A/CHDK/DATA/logo.dat";
2058#else   // CHDK-DE
2059            const char *logo_name="A/CHDK/DATA/logo_de.dat";
2060#endif
2061            FILE *fd;
2062            struct stat st;
2063            need_logo=0;
2064            if (stat(logo_name,&st) == 0) {
2065                logo_size=st.st_size;
2066                logo=malloc(logo_size);
2067                if(logo) {
2068                    fd = fopen(logo_name, "rb");
2069                    if(fd){
2070                        fread(logo,1,logo_size,fd);
2071                        fclose(fd);
2072                    }
2073                    else {
2074                        free(logo);
2075                        logo=NULL;
2076                        need_logo=1;
2077                    }
2078                }
2079            }
2080        }
2081        if (gui_splash>(SPLASH_TIME-4)) {
2082            gui_draw_splash(logo,logo_size);
2083           //   conf.show_osd = 0;
2084        } else if (gui_splash==1 && (mode_get()&MODE_MASK) == gui_splash_mode && (gui_get_mode()==GUI_MODE_NONE || gui_get_mode()==GUI_MODE_ALT)) {
2085            gui_set_need_restore();
2086           // conf.show_osd = 1; //had to uncomment in order to fix a bug with disappearing osd...
2087        }
2088        --gui_splash;
2089        if(!gui_splash) {
2090            free(logo);
2091            logo=NULL;
2092            need_logo=1;
2093        }
2094    }
2095}
2096
2097//-------------------------------------------------------------------
2098
2099#ifdef CAM_DISP_ALT_TEXT
2100
2101static int is_menu_shortcut = 0;
2102
2103static char* gui_shortcut_text(int button)
2104{
2105    switch (button)
2106    {
2107    case KEY_DISPLAY:
2108        return CAM_DISP_BUTTON_NAME;
2109    case KEY_UP:
2110        return "UP";
2111    case KEY_DOWN:
2112        return "DOWN";
2113    case KEY_LEFT:
2114        return "LEFT";
2115    case KEY_RIGHT:
2116        return "RIGHT";
2117    case KEY_ERASE:
2118        return "ERASE";
2119    case KEY_MENU:
2120        is_menu_shortcut = 1;
2121        return "MENU*";
2122    default:
2123        return "?";
2124    }
2125}
2126
2127static int shortcut_text(int x, int y, int button, int func_str, const char *state, color col)
2128{
2129    buf[0] = 0;
2130    if (state)
2131    {
2132        sprintf(buf,"%-5s %20s",gui_shortcut_text(button),lang_str(func_str));
2133        buf[26] = 0;
2134        sprintf(buf+strlen(buf)," [%6s",state);
2135        buf[34] = 0;
2136        strcat(buf,"]");
2137    }
2138    else if (button)
2139    {
2140        sprintf(buf,"%-5s %29s",gui_shortcut_text(button),lang_str(func_str));
2141    }
2142    else
2143    {
2144        sprintf(buf,"%-35s",lang_str(func_str));
2145    }
2146    buf[35] = 0;
2147    draw_string(x, y, buf, col);
2148    return y + FONT_HEIGHT;
2149}
2150
2151static int gui_helper_displayat = 0;
2152
2153void gui_reset_alt_helper()
2154{
2155    gui_helper_displayat = get_tick_count() + (conf.show_alt_helper_delay * 1000);
2156}
2157
2158static void gui_draw_alt_helper()
2159{
2160    if ((camera_info.state.state_kbd_script_run != 0) || (console_displayed != 0))
2161    {
2162        if (gui_helper_displayat <= get_tick_count())
2163            gui_set_need_restore();
2164        gui_reset_alt_helper();
2165    }
2166
2167    if ((conf.show_alt_helper == 0) || (gui_helper_displayat > get_tick_count()))
2168    {
2169        gui_draw_osd();
2170        return;
2171    }
2172
2173    is_menu_shortcut = 0;
2174
2175    int y = FONT_HEIGHT;
2176    int x = ((CAM_SCREEN_WIDTH/2)-(FONT_WIDTH*35/2));
2177
2178    sprintf(buf,lang_str(LANG_HELP_HEADER),
2179            lang_str(LANG_HELP_ALT_SHORTCUTS),
2180            (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_USER_MENU):lang_str(LANG_HELP_CHDK_MENU));
2181    buf[35] = 0;
2182    draw_string(x, y, buf, MAKE_COLOR(COLOR_FG, COLOR_ALT_BG));
2183    y += FONT_HEIGHT;
2184
2185    if (conf.user_menu_enable)
2186    {
2187        sprintf(buf,lang_str(LANG_HELP_HEADER),
2188                lang_str(LANG_HELP_HALF_PRESS),
2189                (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_CHDK_MENU):lang_str(LANG_HELP_USER_MENU));
2190        buf[35] = 0;
2191        draw_string(x, y, buf, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2192        y += FONT_HEIGHT;
2193    }
2194
2195    draw_string(x, y, lang_str(LANG_HELP_SCRIPTS), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2196    y += FONT_HEIGHT;
2197
2198#if !defined(CAM_HAS_MANUAL_FOCUS) && defined(SHORTCUT_MF_TOGGLE)
2199    y = shortcut_text(x, y, SHORTCUT_MF_TOGGLE,LANG_HELP_MANUAL_FOCUS,gui_on_off_enum(0,&conf.subj_dist_override_koef), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2200#endif
2201
2202    if (shooting_get_common_focus_mode())           // Check in manual focus mode
2203    {
2204        sprintf(buf,lang_str(LANG_HELP_FOCUS),gui_shortcut_text(SHORTCUT_SET_INFINITY),gui_shortcut_text(SHORTCUT_SET_HYPERFOCAL));
2205        draw_string(x, y, buf, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2206        y += FONT_HEIGHT;
2207    }
2208
2209#if !CAM_HAS_ERASE_BUTTON && CAM_CAN_SD_OVERRIDE
2210#ifdef OPT_DEBUGGING
2211    if (conf.debug_shortcut_action)
2212        y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2213    else
2214#endif
2215    if (shooting_get_common_focus_mode())           // Check in manual focus mode
2216    {
2217#if CAM_HAS_ZOOM_LEVER
2218        if (SHORTCUT_TOGGLE_RAW != SHORTCUT_SET_INFINITY)
2219            y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_INF_FOCUS, 0, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2220#else
2221        y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_CHG_FOCUS_FACTOR, 0, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2222#endif
2223    }
2224    else
2225        y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2226#else
2227#ifdef OPT_DEBUGGING
2228    if (conf.debug_shortcut_action)
2229        y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2230    else
2231#endif
2232        y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2233#endif
2234
2235    y = shortcut_text(x, y, 0 ,LANG_HELP_HALF_PRESS, 0, MAKE_COLOR(COLOR_FG, COLOR_ALT_BG));
2236
2237    if ( conf.enable_shortcuts)
2238    {
2239        y = shortcut_text(x, y, SHORTCUT_DISABLE_OVERRIDES,LANG_MENU_OVERRIDE_DISABLE,gui_override_disable_modes[conf.override_disable], MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2240        y = shortcut_text(x, y, SHORTCUT_TOGGLE_HISTO,LANG_MENU_HISTO_SHOW,gui_histo_show_modes[conf.show_histo], MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2241        y = shortcut_text(x, y, SHORTCUT_TOGGLE_ZEBRA,LANG_MENU_ZEBRA_DRAW,gui_on_off_enum(0,&conf.zebra_draw), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2242        y = shortcut_text(x, y, SHORTCUT_TOGGLE_OSD,LANG_MENU_OSD_SHOW,gui_on_off_enum(0,&conf.show_osd), MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2243    }
2244    else
2245    {
2246        y = shortcut_text(x, y, 0,LANG_HELP_SHORTCUTS_DISABLED, 0, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2247    }
2248
2249    if (conf.hide_osd == 0)
2250        y = shortcut_text(x, y, KEY_DISPLAY, LANG_HELP_HIDE_OSD, 0, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2251
2252    if (is_menu_shortcut)
2253        y = shortcut_text(x, y, 0 ,LANG_HELP_NOT_ALT, 0, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2254}
2255
2256#endif
2257
2258//-------------------------------------------------------------------
2259void gui_chdk_draw()
2260{
2261#ifdef CAM_DISP_ALT_TEXT
2262    gui_draw_alt_helper();
2263    draw_string(((CAM_SCREEN_WIDTH/2)-(FONT_WIDTH*5/2)), (CAM_SCREEN_HEIGHT-FONT_HEIGHT), "<ALT>", MAKE_COLOR(COLOR_RED, COLOR_WHITE));
2264#else
2265    gui_draw_osd();
2266#endif
2267
2268    if ((mode_get()&MODE_MASK) == MODE_REC || (mode_get()&MODE_MASK) == MODE_PLAY)
2269    {
2270        draw_txt_string(0, 14, script_title, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
2271    }
2272
2273    console_draw();
2274}
2275
2276//-------------------------------------------------------------------
2277static void gui_debug_shortcut(void)
2278{
2279#ifdef OPT_DEBUGGING
2280    static int lastcall = -1;
2281    int t=get_tick_count();
2282    if ( lastcall != -1) {
2283        if (t-lastcall <= 400)
2284            debug_display_direction = -debug_display_direction;
2285    }
2286    lastcall=t;
2287    switch(conf.debug_shortcut_action) {
2288            case 1:
2289                schedule_memdump();
2290                break;
2291            case 2:
2292                gui_update_debug_page();
2293                break;
2294            case 3:
2295                gui_compare_props(1);
2296                break;
2297    }
2298#endif
2299}
2300
2301//-------------------------------------------------------------------
2302// Handler for Menu button press default - enter Menu mode
2303void gui_default_kbd_process_menu_btn()
2304{
2305    gui_set_mode(&menuGuiHandler);
2306}
2307
2308// Change SD override factor, direction = 1 to increase, -1 to decrease
2309// Only applies if camera has a Zoom lever
2310#if CAM_HAS_ZOOM_LEVER
2311static void sd_override_koef(int direction)
2312{
2313    if (direction > 0)
2314    {
2315        if (conf.subj_dist_override_koef==SD_OVERRIDE_OFF)
2316        {
2317            conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2318            menu_set_increment_factor(1);
2319        }
2320        else if (menu_get_increment_factor() < menu_calc_max_increment_factor(MAX_DIST))
2321        {
2322            menu_set_increment_factor(menu_get_increment_factor() * 10);
2323        }
2324        else
2325        {
2326            conf.subj_dist_override_koef = SD_OVERRIDE_INFINITY;
2327        }
2328    }
2329    else if (direction < 0)
2330    {
2331        if (conf.subj_dist_override_koef==SD_OVERRIDE_INFINITY)
2332        {
2333            conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2334            menu_set_increment_factor(menu_calc_max_increment_factor(MAX_DIST));
2335        }
2336        else if (menu_get_increment_factor() > 1)
2337        {
2338            menu_set_increment_factor(menu_get_increment_factor() / 10);
2339        }
2340        else
2341        {
2342            conf.subj_dist_override_koef = SD_OVERRIDE_OFF;
2343        }
2344    }
2345    shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2346}
2347#endif
2348
2349// Change SD override by factor amount, direction = 1 to increase (zoom in), -1 to decrease (zoom out)
2350static void sd_override(int direction)
2351{
2352    if (conf.subj_dist_override_koef == SD_OVERRIDE_ON)
2353    {
2354        gui_subj_dist_override_value_enum(direction*menu_get_increment_factor(),0);
2355        shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
2356    }
2357}
2358
2359static int alt_mode_script_run()
2360{
2361    int remote_script_start_ready = 0;
2362
2363    // Start the current script if script_start is enabled, we are in <ALT> mode and there is a pulse longer than 100mSec on USB port
2364    if (conf.remote_enable && conf.remote_enable_scripts && get_usb_power(SINGLE_PULSE) > 5)
2365        remote_script_start_ready=1;
2366
2367    // Start a script if the shutter button pressed in <ALT> mode (kdb_blocked) or USB remote sequence not running
2368    if (kbd_is_key_clicked(KEY_SHOOT_FULL) || remote_script_start_ready )
2369    {
2370        script_start_gui(0);
2371        return 1;
2372    }
2373
2374    return 0;
2375}
2376
2377// Main button processing for CHDK Alt mode (not in MENU mode)
2378// This needs to be cleaned up, re-organised and commented !!!!
2379int gui_chdk_kbd_process()
2380{
2381    if (alt_mode_script_run()) return 0;
2382
2383    // Process Shutter Half Press + BUTTON shortcuts
2384    gui_kbd_shortcuts();
2385    if (camera_info.state.is_shutter_half_press) return 0;
2386
2387    int reset_helper = 0;
2388
2389#if !CAM_HAS_ERASE_BUTTON && CAM_CAN_SD_OVERRIDE        // ALT RAW toggle kbd processing if camera has SD override but no erase button
2390    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2391    {
2392        if (conf.debug_shortcut_action > 0)
2393        {
2394            gui_debug_shortcut();
2395        }
2396        // Check in manual focus mode
2397        else if (!shooting_get_common_focus_mode())
2398        {
2399            // Not manual focus mode so just update RAW save setting
2400            conf.save_raw = !conf.save_raw;
2401            gui_set_need_restore();
2402        }
2403        else
2404        {
2405            // In manual focus mode so update shooting distance
2406#if CAM_HAS_ZOOM_LEVER
2407            conf.subj_dist_override_value=MAX_DIST;
2408            shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2409#else
2410            gui_subj_dist_override_koef_enum(1,0);
2411#endif
2412            reset_helper = 1;
2413        }
2414    }
2415#else                                                   // ALT RAW toggle kbd processing if can't SD override or has erase button
2416    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2417    {
2418        if (conf.debug_shortcut_action > 0)
2419        {
2420            gui_debug_shortcut();
2421        }
2422        else
2423        {
2424            // Change RAW save state
2425            conf.save_raw = !conf.save_raw;
2426            gui_set_need_restore();
2427        }
2428    }
2429#endif
2430    else if (kbd_is_key_clicked(KEY_SET))
2431    {
2432        gui_menu_init(&script_submenu);
2433        gui_default_kbd_process_menu_btn();
2434    }
2435#if CAM_CAN_SD_OVERRIDE                                 // ALT button processing if camera has SD override
2436    else
2437    {
2438#if !CAM_HAS_MANUAL_FOCUS
2439        if (kbd_is_key_clicked(SHORTCUT_MF_TOGGLE))     // Camera does not have manual focus
2440        {
2441            if (conf.subj_dist_override_koef>SD_OVERRIDE_OFF)
2442                conf.subj_dist_override_koef=SD_OVERRIDE_OFF;
2443            else conf.subj_dist_override_koef=SD_OVERRIDE_ON;
2444            reset_helper = 1;
2445        }
2446        else
2447#endif
2448        if (shooting_get_common_focus_mode())           // Check in manual focus mode
2449        {
2450#if CAM_HAS_ZOOM_LEVER                                  // Camera has zoom lever, use left & right to change factor,up to set infinity
2451            if (kbd_is_key_clicked(KEY_RIGHT))
2452            {
2453                sd_override_koef(1);
2454                reset_helper = 1;
2455            }
2456            else if (kbd_is_key_clicked(KEY_LEFT))
2457            {
2458                sd_override_koef(-1);
2459                reset_helper = 1;
2460            }
2461            else if (kbd_is_key_clicked(SHORTCUT_SET_INFINITY))
2462            {
2463                conf.subj_dist_override_value=MAX_DIST;
2464                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2465                reset_helper = 1;
2466            }
2467            else
2468#endif
2469            if (kbd_is_key_clicked(SHORTCUT_SET_HYPERFOCAL))    // Set hyperfocal distance if down pressed
2470            {
2471                int m=mode_get()&MODE_SHOOTING_MASK;
2472                if ((m==MODE_M) || (m==MODE_AV))
2473                    conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance_1e3_f(shooting_get_aperture_from_av96(shooting_get_user_av96()),get_focal_length(lens_get_zoom_point()))/1000;
2474                else conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance();
2475                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2476                reset_helper = 1;
2477            }
2478            else
2479            {
2480                switch (kbd_get_autoclicked_key())
2481                {
2482#if CAM_HAS_ZOOM_LEVER
2483                case KEY_ZOOM_IN:
2484#else
2485                case KEY_RIGHT:
2486#endif
2487                    sd_override(1);
2488                    reset_helper = 1;
2489                    break;
2490#if CAM_HAS_ZOOM_LEVER
2491                case KEY_ZOOM_OUT:
2492#else
2493                case KEY_LEFT:
2494#endif
2495                    sd_override(-1);
2496                    reset_helper = 1;
2497                    break;
2498                }
2499            }
2500        }
2501    }
2502#endif
2503
2504    if (reset_helper)
2505    {
2506        gui_set_need_restore();
2507#ifdef CAM_DISP_ALT_TEXT
2508        gui_reset_alt_helper();
2509#endif
2510    }
2511
2512    return 0;
2513}
2514
2515//-------------------------------------------------------------------
2516// Handler for Menu button press in CHDK Alt mode (not in Menu mode)
2517// Enter main menu or user menu based on configuration
2518void gui_chdk_kbd_process_menu_btn()
2519{
2520    if (conf.user_menu_enable &&
2521        ((conf.user_menu_as_root && !camera_info.state.is_shutter_half_press) ||
2522         (!conf.user_menu_as_root && camera_info.state.is_shutter_half_press)))
2523        gui_menu_init(&user_submenu);
2524    else
2525        gui_menu_init(&root_menu);
2526
2527    gui_default_kbd_process_menu_btn();
2528}
2529
2530//-------------------------------------------------------------------
2531// GUI handler for <ALT> mode
2532gui_handler altGuiHandler = { GUI_MODE_ALT, gui_chdk_draw, gui_chdk_kbd_process, gui_chdk_kbd_process_menu_btn, 0, };
2533
2534//-------------------------------------------------------------------
2535// Main GUI redraw function, perform common initialisation then calls the redraw handler for the mode
2536void gui_redraw()
2537{
2538    int flag_gui_enforce_redraw = 0;
2539
2540    if (!draw_test_guard() && gui_get_mode())     // Attempt to detect screen erase in <Alt> mode, redraw if needed
2541    {
2542        draw_set_guard();
2543        flag_gui_enforce_redraw = 1;
2544#ifdef CAM_TOUCHSCREEN_UI
2545        redraw_buttons = 1;
2546#endif
2547    }
2548
2549    gui_handle_splash();
2550
2551#ifdef CAM_TOUCHSCREEN_UI
2552    extern void virtual_buttons();
2553    virtual_buttons();
2554#endif
2555
2556    // Erase screen if needed
2557    if (gui_osd_need_restore)
2558    {
2559        draw_restore();
2560        gui_osd_need_restore = 0;
2561        flag_gui_enforce_redraw = 1;
2562    }
2563
2564    // Force mode redraw if needed
2565    if (gui_mode_need_redraw)
2566    {
2567        gui_mode_need_redraw = 0;
2568            flag_gui_enforce_redraw = 1;
2569    }
2570
2571// DEBUG: uncomment if you want debug values always on top
2572//gui_draw_debug_vals_osd();
2573
2574    // Call redraw handler
2575    if (gui_mode->redraw)
2576        gui_mode->redraw(flag_gui_enforce_redraw);
2577}
2578
2579//-------------------------------------------------------------------
2580// Main kbd processing for GUI modes
2581// Return:
2582//          0 = normal
2583//          1 = block buttons pressed from Camera firmware
2584int gui_kbd_process()
2585{
2586    if (gui_mode)
2587    {
2588        // Call menu button handler if menu button pressed
2589        if (gui_mode->kbd_process_menu_btn)
2590        {
2591            if (kbd_is_key_clicked(KEY_MENU))
2592            {
2593                gui_mode->kbd_process_menu_btn();
2594                return 0;
2595            }
2596        }
2597
2598        // Call mode handler for other buttons
2599        if (gui_mode->kbd_process) return gui_mode->kbd_process();
2600    }
2601    return 0;
2602}
2603
2604//-------------------------------------------------------------------
2605static int gui_current_alt_state = ALT_MODE_NORMAL;
2606
2607// Called from the KBD task code to change ALT mode state
2608void gui_set_alt_mode_state(int new_state)
2609{
2610    gui_current_alt_state = new_state;
2611}
2612
2613// Called from the GUI task code to set the ALT mode state
2614void gui_activate_alt_mode()
2615{
2616    switch (gui_current_alt_state)
2617    {
2618    case ALT_MODE_ENTER:
2619        conf_store_old_settings();
2620
2621                extern gui_handler scriptGuiHandler;
2622       
2623            if (camera_info.state.state_kbd_script_run)
2624                gui_set_mode(&scriptGuiHandler);
2625                else
2626                gui_set_mode(&altGuiHandler);
2627
2628        conf_update_prevent_shutdown();
2629       
2630        vid_turn_off_updates();
2631
2632        // If user menu set to start automatically when <ALT> mode entered
2633        // then enter user menu mode, unless a script was paused by exiting
2634        // <ALT> mode when the script was running.
2635            gui_user_menu_flag = 0;
2636            if ((conf.user_menu_enable == 2) && !camera_info.state.state_kbd_script_run) {
2637                    gui_menu_init(&user_submenu);
2638                    gui_set_mode(&menuGuiHandler);
2639                    gui_user_menu_flag = 1;
2640            }
2641        break;
2642
2643    case ALT_MODE_LEAVE:
2644        conf_save_new_settings_if_changed();
2645
2646        // Unload all modules which are marked as safe to unload, or loaded for menus
2647        module_exit_alt();
2648
2649        rbf_set_codepage(FONT_CP_WIN);
2650        vid_turn_on_updates();
2651        gui_set_mode(&defaultGuiHandler);
2652
2653            conf_update_prevent_shutdown();
2654        break;
2655    }
2656
2657    // Reset to stable state
2658    gui_current_alt_state = ALT_MODE_NORMAL;
2659}
Note: See TracBrowser for help on using the repository browser.