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

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