root/core/gui.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gui_enum_value_change
  2. gui_change_simple_enum
  3. gui_change_enum2
  4. gui_USB_switch_types_enum
  5. gui_USB_control_modes_enum
  6. gui_remote_input_types_enum
  7. get_expire_days_left
  8. do_expire_check
  9. do_expire_splash
  10. gui_compare_props
  11. save_romlog
  12. gui_menu_edit_hexa_value
  13. gpx_start_stop
  14. show_compass
  15. navigate_to_image
  16. navigate_to_home
  17. mark_timezone
  18. mark_home
  19. cb_gps_menu_reset
  20. gui_draw_read_selected
  21. gui_draw_read
  22. gui_draw_read_last
  23. gui_draw_rbf_selected
  24. gui_draw_load_rbf
  25. submenu_sort
  26. create_module_menu
  27. gui_module_menu
  28. gui_games_menu
  29. gui_tools_menu
  30. gui_menuproc_mkbootdisk
  31. card_break_proc
  32. gui_menuproc_break_card
  33. gui_menuproc_swap_partitions_enum
  34. gui_delete_module_log_callback
  35. gui_delete_module_log
  36. gui_draw_fselect
  37. gui_show_build_info
  38. gui_show_memory_info
  39. lua_native_call_warning
  40. gui_lua_native_call_warning
  41. unsafe_io_warning
  42. gui_unsafe_io_warning
  43. gui_console_clear
  44. gui_console_show
  45. cb_perc
  46. cb_volts
  47. cb_batt_max
  48. cb_batt_min
  49. cb_space_perc
  50. cb_space_mb
  51. gui_video_bitrate_enum
  52. gui_video_min_bitrate_enum
  53. gui_video_af_key_enum
  54. gui_tv_override_value_enum
  55. gui_tv_enum_type_enum
  56. gui_av_override_enum
  57. gui_subj_dist_override_value_enum
  58. gui_subj_dist_override_koef_enum
  59. gui_conf_curve_enum
  60. gui_load_curve_selected
  61. gui_load_curve
  62. gui_decimal_enum
  63. gui_hhmss_enum
  64. gui_flash_power_modes_enum
  65. gui_flash_exp_comp_modes_enum
  66. cb_change_flash_power
  67. cb_change_flash_exp_comp
  68. set_tv_override_menu
  69. gui_load_edge_selected
  70. gui_menuproc_edge_save
  71. gui_menuproc_edge_load
  72. gui_grid_lines_load_selected
  73. gui_grid_lines_load
  74. gui_menu_run_palette
  75. gui_menu_test_palette
  76. gui_menu_reset_colors_selected
  77. gui_menu_reset_colors
  78. cb_change_rotate_osd
  79. cb_change_dng
  80. cb_change_save_raw
  81. gui_dng_version
  82. gui_dng_crop_size
  83. gui_menuproc_badpixel_create
  84. raw_fselect_cb
  85. gui_raw_develop
  86. cb_zebra_restore_screen
  87. cb_zebra_restore_osd
  88. gui_draw_lang_selected
  89. gui_draw_load_lang
  90. gui_font_enum
  91. gui_draw_menu_rbf_selected
  92. gui_draw_load_menu_rbf
  93. gui_draw_symbol_rbf_selected
  94. gui_draw_load_symbol_rbf
  95. gui_menuproc_reset_files
  96. gui_user_menu_show_enum
  97. gui_alt_mode_button_enum
  98. gui_extra_button_enum
  99. gui_raw_toggle_enum
  100. gui_alt_power_enum
  101. gui_menuproc_reset_selected
  102. gui_menuproc_reset
  103. set_usermenu_state
  104. gui_on_off_enum
  105. gui_override_disable_enum
  106. gui_nd_filter_state_enum
  107. gui_histo_show_enum
  108. init_splash
  109. gui_draw_splash
  110. gui_handle_splash
  111. gui_set_need_restore
  112. gui_cancel_need_restore
  113. gui_set_need_redraw
  114. gui_init
  115. gui_set_mode
  116. gui_shortcut_text
  117. shortcut_text
  118. gui_reset_alt_helper
  119. gui_draw_alt_helper
  120. gui_chdk_draw
  121. gui_debug_shortcut
  122. gui_default_kbd_process_menu_btn
  123. sd_override_koef
  124. sd_override
  125. alt_mode_script_run
  126. gui_chdk_kbd_process
  127. gui_draw_no_module_warning
  128. gui_chdk_kbd_process_menu_btn
  129. gui_redraw
  130. gui_kbd_process
  131. gui_touch_process
  132. gui_set_alt_mode_state
  133. gui_activate_alt_mode

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

/* [<][>][^][v][top][bottom][index][help] */