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_get_mode
  116. gui_set_mode
  117. gui_shortcut_text
  118. shortcut_text
  119. gui_reset_alt_helper
  120. gui_draw_alt_helper
  121. gui_chdk_draw
  122. gui_debug_shortcut
  123. gui_default_kbd_process_menu_btn
  124. sd_override_koef
  125. sd_override
  126. alt_mode_script_run
  127. gui_chdk_kbd_process
  128. gui_draw_no_module_warning
  129. gui_chdk_kbd_process_menu_btn
  130. gui_redraw
  131. gui_kbd_process
  132. gui_touch_process
  133. gui_set_alt_mode_state
  134. 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     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                                  0 ),
1262     {0}
1263 };
1264 
1265 static CMenu video_submenu = {0x23,LANG_MENU_VIDEO_PARAM_TITLE, video_submenu_items };
1266 
1267 //-------------------------------------------------------------------
1268 // "Extra Photo Operations" Menu
1269 
1270 static const char* tv_override[]={
1271 #ifdef CAM_EXT_TV_RANGE
1272     // add very long time exposures as approximately powers of 2, adding 15 exposures
1273     "2048","1625","1290","1024","812","645","512","406","322","256","203","161","128","101","80",
1274 #endif
1275     "64","50.8", "40.3", "32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2", 
1276     "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", 
1277     "1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", 
1278     "1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500",
1279     "1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000", 
1280     "1/32000", "1/40000", "1/50000", "1/64000","1/80000", "1/100k"
1281 };
1282 
1283 const char* gui_tv_override_value_enum(int change, int arg)
1284 {
1285     gui_enum_value_change(&conf.tv_override_value,change,sizeof(tv_override)/sizeof(tv_override[0]));
1286     return tv_override[conf.tv_override_value]; 
1287 }
1288 
1289 static const char* gui_tv_enum_type_enum(int change, int arg)
1290 {
1291 #ifdef CAM_EXT_TV_RANGE
1292     static const char* modes[ ]= { "Ev Step", "ShrtExp", "LongExp" };
1293 #else
1294     static const char* modes[ ]= { "Ev Step", "ShrtExp" };
1295 #endif
1296 
1297     gui_enum_value_change(&conf.tv_enum_type,change,sizeof(modes)/sizeof(modes[0]));
1298     if (change)
1299     {
1300         void set_tv_override_menu(CMenu *menu);
1301         set_tv_override_menu(get_curr_menu());
1302     }
1303     return modes[conf.tv_enum_type]; 
1304 }
1305 
1306 #if CAM_HAS_IRIS_DIAPHRAGM
1307 const char* gui_av_override_enum(int change, int arg)
1308 {
1309     conf.av_override_value+=change;
1310     if (conf.av_override_value<0) conf.av_override_value=shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1;
1311     else if (conf.av_override_value>shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1) conf.av_override_value=0;
1312 
1313     short prop_id = shooting_get_aperture_from_av96(shooting_get_av96_override_value())/10;
1314     sprintf(buf, "%d.%02d", (int)prop_id/100, (int)prop_id%100 );
1315     return buf;
1316 }
1317 #endif
1318 
1319 const char* gui_subj_dist_override_value_enum(int change, int arg)
1320 {
1321     static char buf[9];
1322 
1323     if (conf.subj_dist_override_koef == SD_OVERRIDE_INFINITY)  // Infinity selected
1324         strcpy(buf,"   Inf.");
1325     else
1326     {
1327         // Increment / decrement the SD value, wrapping around from CAMERA_MIN_DIST to CAMERA_MAX_DIST
1328         conf.subj_dist_override_value += (change/**koef*/);
1329         if (conf.subj_dist_override_value < CAMERA_MIN_DIST)
1330             conf.subj_dist_override_value = CAMERA_MAX_DIST;
1331         else if (conf.subj_dist_override_value > CAMERA_MAX_DIST)
1332             conf.subj_dist_override_value = CAMERA_MIN_DIST;
1333         // philmoz 19/6/2014 - if SD override is < distance from sensor to front of lens (for current zoom) then adjust SD override
1334         if (conf.subj_dist_override_value < shooting_get_lens_to_focal_plane_width())
1335             conf.subj_dist_override_value = shooting_get_lens_to_focal_plane_width();
1336         sprintf(buf, "%7d", shooting_get_subject_distance_override_value());
1337     }
1338 
1339     return buf; 
1340 }
1341 
1342 const char* gui_subj_dist_override_koef_enum(int change, int arg)
1343 {
1344     static const char* modes[] = { "Off", "On", "Inf" };
1345         const char *rv = gui_change_simple_enum(&conf.subj_dist_override_koef,change,modes,sizeof(modes)/sizeof(modes[0]));
1346     return rv;
1347 }
1348 
1349 #if defined(OPT_CURVES)
1350 
1351 static const char* gui_conf_curve_enum(int change, int arg) {
1352     static const char* modes[]={ "None", "Custom", "+1EV", "+2EV", "Auto DR" };
1353 
1354     gui_enum_value_change(&conf.curve_enable,change,sizeof(modes)/sizeof(modes[0]));
1355 
1356         if (change)
1357         libcurves->curve_init_mode();
1358     return modes[conf.curve_enable];
1359 }
1360 
1361 static void gui_load_curve_selected(const char *fn)
1362 {
1363         if (fn) {
1364                 // TODO we could sanity check here, but curve_set_type should fail gracefullish
1365                 strcpy(conf.curve_file,fn);
1366                 if (conf.curve_enable == 1)
1367             libcurves->curve_init_mode();
1368         }
1369 }
1370 
1371 static void gui_load_curve(int arg)
1372 {
1373     libfselect->file_select(LANG_STR_SELECT_CURVE_FILE, conf.curve_file, CURVE_DIR, gui_load_curve_selected);
1374 }
1375 
1376 static CMenuItem curve_submenu_items[] = {
1377     MENU_ITEM(0x5f,LANG_MENU_CURVE_ENABLE,        MENUITEM_ENUM,      gui_conf_curve_enum, &conf.curve_enable ),
1378     MENU_ITEM(0x35,LANG_MENU_CURVE_LOAD,          MENUITEM_PROC,      gui_load_curve, 0 ),
1379     MENU_ITEM(0x51,LANG_MENU_BACK,                MENUITEM_UP, 0, 0 ),
1380     {0}
1381 };
1382 
1383 static CMenu curve_submenu = {0x85,LANG_MENU_CURVE_PARAM_TITLE, curve_submenu_items };
1384 
1385 #endif
1386 
1387 // Display & edit an int value as a decimal.
1388 // Value ranges from 0 - 999999; but display shows as 0.00000 - 9.99999
1389 const char* gui_decimal_enum(int change, int arg)
1390 {
1391     int *v = (int*)arg;
1392 
1393     *v += change;
1394     if (*v < 0) *v = 0;
1395     if (*v > 999999) *v = 999999;
1396 
1397     sprintf(buf, "%01d.%05d", (int)(*v / 100000), (int)(*v % 100000));
1398 
1399     return buf;
1400 }
1401 
1402 // Modify and display a value as H:MM:SS
1403 // For storing a value as a number of seconds internally; but displaying as a time value
1404 const char* gui_hhmss_enum(int change, int arg)
1405 {
1406     int *v = (int*)arg;
1407 
1408     int h, m, s;
1409     h = *v / 3600;
1410     m = (*v % 3600) / 60;
1411     s = *v % 60;
1412 
1413     switch (change)
1414     {
1415     case 1:
1416     case -1:
1417         s += change;
1418         if (s < 0) s = 59;
1419         if (s > 59) s = 0;
1420         break;
1421     case 10:
1422     case -10:
1423         m += change / 10;
1424         if (m < 0) m = 59;
1425         if (m > 59) m = 0;
1426         break;
1427     default:
1428         h += change /100;
1429         if (h < 0) h = 1;
1430         if (h > 1) h = 0;
1431         break;
1432     }
1433     *v = (h * 3600) + (m * 60) + s;
1434 
1435     sprintf(buf, "%1d:%02d:%02d", h, m, s);
1436 
1437     return buf;
1438 }
1439 
1440 static const char* gui_override_disable_modes[] =           { "No", "Yes" };
1441 #if CAM_HAS_ND_FILTER
1442 static const char* gui_nd_filter_state_modes[] =            { "Off", "In", "Out" };
1443 #endif
1444 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"};
1445 #if CAM_QUALITY_OVERRIDE
1446 static const char* gui_fast_image_quality_modes[] =         { "Sup.Fine", "Fine", "Normal", "Off" };
1447 #endif
1448 
1449 #ifdef CAM_HOTSHOE_OVERRIDE
1450 static const char* gui_hotshoe_override_modes[] = { (char*)LANG_MENU_HOTSHOE_OVERRIDE_OFF, (char*)LANG_MENU_HOTSHOE_EMPTY, (char*)LANG_MENU_HOTSHOE_USED };
1451 #endif
1452 
1453 const char* gui_flash_power_modes_enum(int change, int arg)
1454 {
1455     static const char* modes[] = { "Min", "Med", "Max" };
1456         const char *rv = gui_change_simple_enum(&conf.flash_video_override_power,change,modes,sizeof(modes)/sizeof(modes[0]));
1457     return rv;
1458 }
1459 
1460 const char* gui_flash_exp_comp_modes_enum(int change, int arg)
1461 {
1462     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" };
1463         const char *rv = gui_change_simple_enum(&conf.flash_exp_comp,change,modes,sizeof(modes)/sizeof(modes[0]));
1464     return rv;
1465 }
1466 
1467 static void cb_change_flash_power()
1468 {
1469     if (conf.flash_manual_override) conf.flash_enable_exp_comp = 0;
1470 }
1471 
1472 static void cb_change_flash_exp_comp()
1473 {
1474     if (conf.flash_enable_exp_comp) conf.flash_manual_override = 0;
1475 }
1476 
1477 static CMenuItem tv_override_evstep[2] = {
1478     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_VALUE,  MENUITEM_ENUM,            gui_tv_override_value_enum,         0 ),
1479     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1480 };
1481 
1482 #ifdef CAM_EXT_TV_RANGE
1483 static CMenuItem tv_override_long_exp[2] = {
1484     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_LONG_EXP,  MENUITEM_ENUM|MENUITEM_HHMMSS, gui_hhmss_enum,             &conf.tv_override_long_exp ),
1485     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1486 };
1487 #endif
1488 
1489 static CMenuItem tv_override_short_exp[2] = {
1490     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_SHORT_EXP, MENUITEM_ENUM|MENUITEM_DECIMAL, gui_decimal_enum,          &conf.tv_override_short_exp ),
1491     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1492 };
1493 
1494 static CMenuItem iso_override_items[2] = {
1495     MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_override_value,           MENU_MINMAX(0, 10000) ),
1496     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.iso_override_koef,            0),
1497 };
1498 
1499 static CMenuItem fast_ev_switch[2] = {
1500     MENU_ENUM2  (0, 0,                                                      &conf.fast_ev_step,                 gui_fast_ev_step_modes ),
1501     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.fast_ev,                      0 ),
1502 };
1503 
1504 static CMenuItem manual_flash[2] = {
1505     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_flash_power_modes_enum,         0 ),
1506     MENU_ITEM   (0, 0,  MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,                &conf.flash_manual_override,        (int)cb_change_flash_power ),
1507 };
1508 
1509 static CMenuItem flash_exp_comp[2] = {
1510     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_flash_exp_comp_modes_enum,      0 ),
1511     MENU_ITEM   (0, 0,  MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,                &conf.flash_enable_exp_comp,        (int)cb_change_flash_exp_comp ),
1512 };
1513 
1514 #if CAM_HAS_IRIS_DIAPHRAGM
1515 static CMenuItem av_override_items[2] = {
1516     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_av_override_enum,               0 ),
1517     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.av_override_enabled,          0 ),
1518 };
1519 #endif
1520 
1521 static CMenuItem sd_override_items[2] = {
1522     MENU_ITEM   (0, 0,   MENUITEM_ENUM|MENUITEM_SD_INT,                     gui_subj_dist_override_value_enum,  CAMERA_MAX_DIST ),
1523     MENU_ITEM   (0, 0,   MENUITEM_ENUM,                                     gui_subj_dist_override_koef_enum,   0 ),
1524 };
1525 
1526 static const char* gui_raw_nr_modes[] =                     { "Auto", "Off", "On"};
1527 
1528 static CMenuItem operation_submenu_items[] = {
1529     MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_DISABLE,           &conf.override_disable, gui_override_disable_modes ),
1530     MENU_ITEM   (0x5c,LANG_MENU_OVERRIDE_DISABLE_ALL,       MENUITEM_BOOL,          &conf.override_disable_all,         0 ),
1531     MENU_ITEM   (0x59,LANG_MENU_TV_ENUM_TYPE,               MENUITEM_ENUM,          gui_tv_enum_type_enum,              0 ),
1532     MENU_ITEM   (0x61,LANG_MENU_OVERRIDE_TV_VALUE,          MENUITEM_STATE_VAL_PAIR,&tv_override_evstep,                0 ),
1533 #if CAM_HAS_IRIS_DIAPHRAGM
1534     MENU_ITEM   (0x62,LANG_MENU_OVERRIDE_AV_VALUE,          MENUITEM_STATE_VAL_PAIR,&av_override_items,                 0 ),
1535 #endif
1536     MENU_ITEM   (0x74,LANG_MENU_OVERRIDE_ISO_VALUE,         MENUITEM_STATE_VAL_PAIR,&iso_override_items,                10 ),
1537     MENU_ITEM   (0x5e,LANG_MENU_OVERRIDE_SUBJ_DIST_VALUE,   MENUITEM_STATE_VAL_PAIR,&sd_override_items,                 0 ),
1538     MENU_ITEM   (0x5c,LANG_MENU_MISC_FAST_EV,               MENUITEM_STATE_VAL_PAIR,&fast_ev_switch,                    0 ),
1539     MENU_ITEM   (0x5c, LANG_MENU_FLASH_EXP_COMP,            MENUITEM_STATE_VAL_PAIR,&flash_exp_comp,                    0 ),
1540     MENU_ITEM   (0x5c, LANG_MENU_FLASH_MANUAL_OVERRIDE,     MENUITEM_STATE_VAL_PAIR,&manual_flash,                      0 ),
1541 #if CAM_HAS_VIDEO_BUTTON
1542     MENU_ITEM   (0x5c, LANG_MENU_FLASH_VIDEO_OVERRIDE,      MENUITEM_BOOL,          &conf.flash_video_override,         0 ),
1543 #endif
1544 #if CAM_REAR_CURTAIN
1545     MENU_ITEM   (0x5c, LANG_MENU_REAR_CURTAIN,              MENUITEM_BOOL,          &conf.flash_sync_curtain,           0 ),
1546 #endif
1547 #ifdef CAM_HOTSHOE_OVERRIDE
1548     MENU_ENUM2  (0x5c, LANG_MENU_HOTSHOE_OVERRIDE,          &conf.hotshoe_override, gui_hotshoe_override_modes ),
1549 #endif
1550 #if CAM_HAS_ND_FILTER
1551     MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_ND_FILTER,         &conf.nd_filter_state,  gui_nd_filter_state_modes ),
1552 #endif
1553     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
1554 #if CAM_QUALITY_OVERRIDE
1555     MENU_ENUM2  (0x5c,LANG_MENU_MISC_IMAGE_QUALITY,         &conf.fast_image_quality, gui_fast_image_quality_modes ),
1556 #endif
1557     MENU_ITEM   (0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,      MENUITEM_SUBMENU,       &bracketing_in_continuous_submenu,  0 ),
1558     MENU_ITEM   (0x2d,LANG_MENU_AUTOISO,                    MENUITEM_SUBMENU,       &autoiso_submenu,                   0 ),
1559 #ifdef OPT_CURVES
1560     MENU_ITEM   (0x85,LANG_MENU_CURVE_PARAM,                MENUITEM_SUBMENU,       &curve_submenu,                     0 ),
1561 #endif
1562     MENU_ITEM   (0x5b,LANG_MENU_CLEAR_OVERRIDE_VALUES,      MENUITEM_BOOL,          &conf.clear_override,               0 ),
1563     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                  0 ),
1564     {0}
1565 };
1566 
1567 static CMenu operation_submenu = {0x21,LANG_MENU_OPERATION_PARAM_TITLE, operation_submenu_items };
1568 
1569 void set_tv_override_menu(CMenu *menu)
1570 {
1571     CMenuItem *mi = find_menu_item(menu,LANG_MENU_OVERRIDE_TV_VALUE);
1572     if (mi)
1573     {
1574         switch (conf.tv_enum_type)
1575         {
1576         case 0:     // Ev Step
1577             mi->value = (int*)(&tv_override_evstep);
1578             mi->arg = 1;
1579             break;
1580         case 1:     // Short exposure
1581             mi->value = (int*)(&tv_override_short_exp);
1582             mi->arg = 100;
1583             break;
1584 #ifdef CAM_EXT_TV_RANGE
1585         case 2:     // Long exposure
1586             mi->value = (int*)(&tv_override_long_exp);
1587             mi->arg = 1;
1588             break;
1589 #endif
1590         }
1591     }
1592 }
1593 
1594 //-------------------------------------------------------------------
1595 
1596 static void gui_load_edge_selected( const char* fn )
1597 {
1598     if (fn)
1599         libedgeovr->load_edge_overlay(fn);
1600 }
1601 
1602 static void gui_menuproc_edge_save(int arg)
1603 {
1604     libedgeovr->save_edge_overlay();
1605 }
1606 
1607 static void gui_menuproc_edge_load(int arg)
1608 {
1609     libfselect->file_select(LANG_MENU_EDGE_LOAD, EDGE_SAVE_DIR, EDGE_SAVE_DIR, gui_load_edge_selected);
1610 }
1611 
1612 static const char* gui_edge_pano_modes[] =                  { "Off", "Right", "Down", "Left", "Up", "Free" };
1613 static CMenuItem edge_overlay_submenu_items[] = {
1614     MENU_ITEM   (0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE,        MENUITEM_BOOL,          &conf.edge_overlay_enable,  0 ),
1615     MENU_ITEM   (0x5c,LANG_MENU_EDGE_FILTER,                MENUITEM_BOOL,          &conf.edge_overlay_filter,  0 ),
1616     MENU_ENUM2  (0x5f,LANG_MENU_EDGE_PANO,                  &conf.edge_overlay_pano, gui_edge_pano_modes ),
1617     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) ),
1618     MENU_ITEM   (0x5c,LANG_MENU_EDGE_SHOW,                  MENUITEM_BOOL,          &conf.edge_overlay_show,    0 ),
1619     MENU_ITEM   (0x5e,LANG_MENU_EDGE_OVERLAY_TRESH,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255) ),
1620     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
1621     MENU_ITEM   (0x33,LANG_MENU_EDGE_SAVE,                  MENUITEM_PROC,          gui_menuproc_edge_save,     0 ),
1622     MENU_ITEM   (0x5c,LANG_MENU_EDGE_ZOOM,                  MENUITEM_BOOL,          &conf.edge_overlay_zoom,    0 ),
1623     MENU_ITEM   (0x33,LANG_MENU_EDGE_LOAD,                  MENUITEM_PROC,          gui_menuproc_edge_load,     0 ),
1624     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                          0 ),
1625     {0}
1626 };
1627 
1628 static CMenu edge_overlay_submenu = {0x7f,LANG_MENU_EDGE_OVERLAY_TITLE, edge_overlay_submenu_items };
1629 
1630 //-------------------------------------------------------------------
1631 
1632 static void gui_grid_lines_load_selected(const char *fn)
1633 {
1634     if (fn)
1635     {
1636         libgrids->grid_lines_load(fn);
1637     }
1638 }
1639 
1640 static void gui_grid_lines_load(int arg)
1641 {
1642     libfselect->file_select(LANG_STR_SELECT_GRID_FILE, conf.grid_lines_file, "A/CHDK/GRIDS", gui_grid_lines_load_selected);
1643 }
1644 
1645 static CMenuItem grid_submenu_items[] = {
1646     MENU_ITEM(0x2f,LANG_MENU_SHOW_GRID,         MENUITEM_BOOL,          &conf.show_grid_lines, 0 ),
1647     MENU_ITEM(0x35,LANG_MENU_GRID_LOAD,         MENUITEM_PROC,          gui_grid_lines_load, 0 ),
1648     MENU_ITEM(0x0,LANG_MENU_GRID_CURRENT,       MENUITEM_SEPARATOR, 0, 0 ),
1649     MENU_ITEM(0x0,(int)conf.grid_title,         MENUITEM_TEXT,      0, 0 ),
1650     MENU_ITEM(0x0,(int)"",                      MENUITEM_SEPARATOR, 0, 0 ),
1651     MENU_ITEM(0x5c,LANG_MENU_GRID_FORCE_COLOR,  MENUITEM_BOOL,      &conf.grid_force_color, 0 ),
1652     MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_LINE,   MENUITEM_COLOR_FG,  &conf.grid_color, 0 ),
1653     MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_FILL,   MENUITEM_COLOR_BG,  &conf.grid_color, 0 ),
1654     MENU_ITEM(0x51,LANG_MENU_BACK,              MENUITEM_UP, 0, 0 ),
1655     {0}
1656 };
1657 
1658 static CMenu grid_submenu = {0x2f,LANG_MENU_GRID_TITLE, grid_submenu_items };
1659 
1660 //-------------------------------------------------------------------
1661 
1662 static void gui_menu_run_palette(int arg)
1663 {
1664     libpalette->show_palette(PALETTE_MODE_DEFAULT, (chdkColor){0,0}, NULL);
1665 }
1666 
1667 static void gui_menu_test_palette(int arg)
1668 {
1669     libpalette->show_palette(PALETTE_MODE_TEST, (chdkColor){0,0}, NULL);
1670 }
1671 
1672 static void gui_menu_reset_colors_selected(unsigned int btn)
1673 {
1674     if (btn==MBOX_BTN_YES)
1675         resetColors();
1676 }
1677 
1678 static void gui_menu_reset_colors(int arg)
1679 {
1680     gui_mbox_init(LANG_MSG_RESET_COLORS_TITLE,
1681                   LANG_MSG_RESET_COLORS_TEXT,
1682                   MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menu_reset_colors_selected);
1683 }
1684 
1685 static CMenuItem visual_submenu_items[] = {
1686     MENU_ITEM(0x65,LANG_MENU_MISC_PALETTE,            MENUITEM_PROC,      gui_menu_run_palette, 0 ),
1687     MENU_ITEM(0x65,LANG_MENU_COLOR_TEST,              MENUITEM_PROC,      gui_menu_test_palette, 0 ),
1688     MENU_ITEM(0x65,LANG_MSG_RESET_COLORS_TITLE,       MENUITEM_PROC,      gui_menu_reset_colors, 0 ),
1689     MENU_ITEM(0x0,LANG_MENU_VIS_COLORS,               MENUITEM_SEPARATOR, 0, 0 ),
1690     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_TEXT,            MENUITEM_COLOR_FG,  &conf.osd_color, 0 ),
1691     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_BKG,             MENUITEM_COLOR_BG,  &conf.osd_color, 0 ),
1692     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING,         MENUITEM_COLOR_FG,  &conf.osd_color_warn, 0 ),
1693     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_warn, 0 ),
1694     MENU_ITEM(0x65,LANG_MENU_EDGE_OVERLAY_COLOR,      MENUITEM_COLOR_FG,  &conf.edge_overlay_color,   0 ),
1695     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO,               MENUITEM_COLOR_FG,  &conf.histo_color, 0 ),
1696     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BKG,           MENUITEM_COLOR_BG,  &conf.histo_color, 0 ),
1697     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BORDER,        MENUITEM_COLOR_FG,  &conf.histo_color2, 0 ),
1698     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_MARKERS,       MENUITEM_COLOR_BG,  &conf.histo_color2, 0 ),
1699     MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_UNDER,         MENUITEM_COLOR_BG,  &conf.zebra_color, 0 ),
1700     MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_OVER,          MENUITEM_COLOR_FG,  &conf.zebra_color, 0 ),
1701     //MENU_ITEM(0x65,LANG_MENU_VIS_BATT_ICON,           MENUITEM_COLOR_FG,  &conf.batt_icon_color, 0 ),
1702     MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON,          MENUITEM_COLOR_FG,  &conf.space_color, 0 ),
1703     MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON_BKG,      MENUITEM_COLOR_BG,  &conf.space_color, 0 ),
1704     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TEXT,           MENUITEM_COLOR_FG,  &conf.menu_color, 0 ),
1705     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_BKG,            MENUITEM_COLOR_BG,  &conf.menu_color, 0 ),
1706     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_TEXT,     MENUITEM_COLOR_FG,  &conf.menu_title_color, 0 ),
1707     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_BKG,      MENUITEM_COLOR_BG,  &conf.menu_title_color, 0 ),
1708     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_cursor_color, 0 ),
1709     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_BKG,     MENUITEM_COLOR_BG,  &conf.menu_cursor_color, 0 ),
1710     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_symbol_color, 0 ),
1711     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_BKG,     MENUITEM_COLOR_BG,  &conf.menu_symbol_color, 0 ),
1712     MENU_ITEM(0x65,LANG_MENU_VIS_READER_TEXT,         MENUITEM_COLOR_FG,  &conf.reader_color, 0 ),
1713     MENU_ITEM(0x65,LANG_MENU_VIS_READER_BKG,          MENUITEM_COLOR_BG,  &conf.reader_color, 0 ),
1714     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE,         MENUITEM_COLOR_FG,  &conf.osd_color_override, 0 ),
1715     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_override, 0 ),
1716     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1717     {0}
1718 };
1719 
1720 static CMenu visual_submenu = {0x28,LANG_MENU_VIS_TITLE, visual_submenu_items };
1721 
1722 //-------------------------------------------------------------------
1723 
1724 static CMenuItem raw_state_submenu_items[] = {
1725     MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_RAW_STATE,         MENUITEM_BOOL,      &conf.show_raw_state,       0 ),
1726     MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_REMAINING_RAW,     MENUITEM_BOOL,      &conf.show_remaining_raw,   0 ),
1727     MENU_ITEM   (0x60,LANG_MENU_OSD_RAW_TRESHOLD,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.remaining_raw_treshold,   MENU_MINMAX(0, 200) ),
1728     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1729     {0}
1730 };
1731 
1732 static CMenu raw_state_submenu = {0x24,LANG_MENU_OSD_RAW_STATE_PARAMS_TITLE, raw_state_submenu_items };
1733 
1734 //-------------------------------------------------------------------
1735 
1736 #ifdef  CAM_TOUCHSCREEN_UI
1737 
1738 static const char* gui_touchscreen_disable_modes[]=         { "Enable", "Disable" };
1739 
1740 static CMenuItem touchscreen_submenu_items[] = {
1741     MENU_ENUM2  (0x5f,LANG_MENU_TS_VIDEO_AE_DISABLE,        &conf.touchscreen_disable_video_controls,    gui_touchscreen_disable_modes ),
1742     MENU_ENUM2  (0x5f,LANG_MENU_TS_ALT_SHORTCUTS_DISABLE,   &conf.touchscreen_disable_shortcut_controls, gui_touchscreen_disable_modes ),
1743     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0, 0 ),
1744     {0}
1745 };
1746 
1747 static CMenu touchscreen_submenu = {0x28,LANG_MENU_TOUCHSCREEN_VALUES, touchscreen_submenu_items };
1748 
1749 #endif
1750 
1751 //-------------------------------------------------------------------
1752 static void cb_change_rotate_osd()
1753 {
1754     update_draw_proc();
1755     gui_menu_erase_and_redraw();
1756 }
1757 
1758 #ifdef CAM_HAS_CMOS
1759     static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CMOS", "Battery", "all" };
1760 #else
1761     static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CCD", "Battery", "all" };
1762 #endif
1763 static const char* gui_hide_osd_modes[] =                   { "Don't", "In Playback", "On Disp Press", "Both" };
1764 static const char* gui_show_usb_info_modes[] =              { "Off", "Icon", "Text" };
1765 
1766 static CMenuItem osd_submenu_items[] = {
1767     MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW,              MENUITEM_BOOL,          &conf.show_osd, 0 ),
1768     MENU_ENUM2(0x5c,LANG_MENU_OSD_HIDE_PLAYBACK,                            &conf.hide_osd, gui_hide_osd_modes ),
1769     MENU_ITEM(0x5c,LANG_MENU_OSD_ROTATE,            MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.rotate_osd, (int)cb_change_rotate_osd ),
1770     MENU_ITEM(0x5f,LANG_MENU_OSD_SHOW_STATES,       MENUITEM_BOOL,          &conf.show_state, 0 ),
1771     MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_TEMP,                                &conf.show_temp, gui_temp_mode_modes ),
1772     MENU_ITEM(0x59,LANG_MENU_OSD_TEMP_FAHRENHEIT,   MENUITEM_BOOL,          &conf.temperature_unit, 0 ),
1773     MENU_ENUM2(0x71,LANG_MENU_USB_SHOW_INFO,                                &conf.usb_info_enable, gui_show_usb_info_modes ),
1774     MENU_ITEM(0x22,LANG_MENU_OSD_VALUES,                MENUITEM_SUBMENU,       &values_submenu, 0 ),
1775     MENU_ITEM(0x31,LANG_MENU_OSD_DOF_CALC,          MENUITEM_SUBMENU,       &dof_submenu, 0 ),
1776     MENU_ITEM(0x24,LANG_MENU_OSD_RAW_STATE_PARAMS,  MENUITEM_SUBMENU,       &raw_state_submenu, 0 ),
1777     MENU_ITEM(0x32,LANG_MENU_OSD_BATT_PARAMS,       MENUITEM_SUBMENU,       &battery_submenu, 0 ),
1778     MENU_ITEM(0x33,LANG_MENU_OSD_SPACE_PARAMS,      MENUITEM_SUBMENU,       &space_submenu, 0 ),
1779     MENU_ITEM(0x34,LANG_MENU_OSD_CLOCK_PARAMS,          MENUITEM_SUBMENU,       &clock_submenu, 0 ),
1780     MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_IN_REVIEW,    MENUITEM_BOOL,          &conf.show_osd_in_review, 0 ),
1781     MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_HIDDENFILES,  MENUITEM_BOOL,          &conf.show_hiddenfiles, 0 ),
1782 #ifdef  CAM_TOUCHSCREEN_UI
1783     MENU_ITEM   (0x22,LANG_MENU_TOUCHSCREEN_VALUES,         MENUITEM_SUBMENU,   &touchscreen_submenu,       0 ),
1784 #endif
1785     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0,                                 0 ),
1786     {0}
1787 };
1788 
1789 static CMenu osd_submenu = {0x22,LANG_MENU_OSD_TITLE, osd_submenu_items };
1790 
1791 //-------------------------------------------------------------------
1792 
1793 static const char* gui_histo_show_modes[] =                 { "Don't", "Always", "Rec", "Shoot" };
1794 static const char* gui_histo_view_modes[]={ "RGB", "Y", "RGB Y",  "R G B", "RGB all", "Y all", "Blend", "Blend Y"};
1795 static const char* gui_histo_transform_modes[]={ "Linear", "Log" };
1796 
1797 static CMenuItem histo_submenu_items[] = {
1798     MENU_ENUM2(0x5f,LANG_MENU_HISTO_SHOW,             &conf.show_histo,     gui_histo_show_modes ),
1799     MENU_ENUM2(0x6f,LANG_MENU_HISTO_LAYOUT,           &conf.histo_layout,   gui_histo_view_modes ),
1800     MENU_ENUM2(0x5f,LANG_MENU_HISTO_MODE,             &conf.histo_mode,     gui_histo_transform_modes ),
1801     MENU_ITEM(0x5c,LANG_MENU_HISTO_EXP,               MENUITEM_BOOL,       &conf.show_overexp, 0 ),
1802     MENU_ITEM(0x70,LANG_MENU_HISTO_IGNORE_PEAKS,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.histo_ignore_boundary,   MENU_MINMAX(0, 32) ),
1803     MENU_ITEM(0x5c,LANG_MENU_HISTO_MAGNIFY,           MENUITEM_BOOL,       &conf.histo_auto_ajust, 0 ),
1804     MENU_ITEM(0x5c,LANG_MENU_HISTO_SHOW_EV_GRID,      MENUITEM_BOOL,       &conf.histo_show_ev_grid, 0 ),
1805     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1806     {0}
1807 };
1808 
1809 static CMenu histo_submenu = {0x25,LANG_MENU_HISTO_TITLE, histo_submenu_items };
1810 
1811 //-------------------------------------------------------------------
1812 
1813 static CMenuItem raw_exceptions_submenu_items[] = {
1814 #if defined CAM_HAS_VIDEO_BUTTON
1815     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_VIDEO,          MENUITEM_BOOL,      &conf.save_raw_in_video,        0 ),
1816 #endif
1817 #if defined(CAM_HAS_SPORTS_MODE)
1818     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_SPORTS,         MENUITEM_BOOL,      &conf.save_raw_in_sports,       0 ),
1819 #endif
1820     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_BURST,          MENUITEM_BOOL,      &conf.save_raw_in_burst,        0 ),
1821     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_TIMER,          MENUITEM_BOOL,      &conf.save_raw_in_timer,        0 ),
1822     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EDGEOVERLAY,    MENUITEM_BOOL,      &conf.save_raw_in_edgeoverlay,  0 ),
1823     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_AUTO,           MENUITEM_BOOL,      &conf.save_raw_in_auto,         0 ),
1824 #if defined(CAM_HAS_CANON_RAW)
1825     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_CANON_RAW,      MENUITEM_BOOL,      &conf.save_raw_in_canon_raw,    0 ),
1826 #endif
1827 #if CAM_BRACKETING
1828     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EV_BRACKETING,  MENUITEM_BOOL,      &conf.save_raw_in_ev_bracketing, 0 ),
1829 #endif
1830     MENU_ITEM   (0x5c,LANG_MENU_RAW_WARN,                   MENUITEM_BOOL,      &conf.raw_exceptions_warn,      0 ),
1831     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                              0 ),
1832     {0}
1833 };
1834 
1835 static CMenu raw_exceptions_submenu = {0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS_TITLE, raw_exceptions_submenu_items };
1836 
1837 //-------------------------------------------------------------------
1838 
1839 static void cb_change_dng()
1840 {
1841     int old=conf.dng_version;
1842     conf_change_dng();
1843     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);
1844 }
1845 
1846 static void cb_change_save_raw()
1847 {
1848     if ( conf.enable_raw_shortcut )
1849     {
1850         conf.save_raw = !conf.save_raw;
1851         cb_change_dng();
1852         gui_set_need_restore();
1853         if ( conf.enable_raw_shortcut == 2 ) conf.show_raw_state = conf.save_raw;
1854     }
1855 }
1856 
1857 static const char* gui_dng_version(int change, int arg)
1858 {
1859     static const char* modes[]={ "1.3", "1.1" };
1860 
1861     gui_enum_value_change(&conf.dng_version,change,sizeof(modes)/sizeof(modes[0]));
1862     cb_change_dng();
1863 
1864     return modes[conf.dng_version];
1865 }
1866 
1867 static const char* gui_dng_crop_size(int change, int arg)
1868 {
1869     static const char* modes[]={ "JPEG", "Active", "Full" };
1870 
1871     gui_enum_value_change(&conf.dng_crop_size,change,sizeof(modes)/sizeof(modes[0]));
1872 
1873     return modes[conf.dng_crop_size];
1874 }
1875 
1876 static void gui_menuproc_badpixel_create(int arg)
1877 {
1878     libdng->create_badpixel_bin();
1879 }
1880 
1881 static void raw_fselect_cb(const char * filename)
1882 {
1883     raw_prepare_develop(filename, 1);
1884 }
1885 
1886 static void gui_raw_develop(int arg)
1887 {
1888     libfselect->file_select(LANG_RAW_DEVELOP_SELECT_FILE, "A/DCIM", "A", raw_fselect_cb);
1889 }
1890 
1891 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};
1892 
1893 #if defined (DNG_EXT_FROM)
1894 extern void cb_change_dng_usb_ext();
1895 #endif
1896 
1897 static CMenuItem raw_submenu_items[] = {
1898     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE,                   MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.save_raw, (int)cb_change_dng ),
1899     MENU_ITEM   (0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS,      MENUITEM_SUBMENU,   &raw_exceptions_submenu, 0 ),
1900     MENU_ITEM   (0x5c,LANG_MENU_RAW_FIRST_ONLY,             MENUITEM_BOOL,      &conf.raw_save_first_only, 0 ),
1901     MENU_ENUM2a (0x5f,LANG_MENU_RAW_SAVE_IN_DIR,            &conf.raw_in_dir,   img_folders, NUM_IMG_FOLDER_NAMES ),
1902     MENU_ENUM2a (0x5f,LANG_MENU_RAW_PREFIX,                 &conf.raw_prefix,   img_prefixes, NUM_IMG_PREFIXES ),
1903     MENU_ENUM2a (0x5f,LANG_MENU_RAW_EXTENSION,              &conf.raw_ext,      img_exts, NUM_IMG_EXTS ),
1904     MENU_ENUM2a (0x5f,LANG_MENU_SUB_PREFIX,                 &conf.sub_batch_prefix, img_prefixes, NUM_IMG_PREFIXES ),
1905     MENU_ENUM2a (0x5f,LANG_MENU_SUB_EXTENSION,              &conf.sub_batch_ext, img_exts, NUM_IMG_EXTS ),
1906 //  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) ),
1907 //  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) ),
1908     MENU_ITEM   (0x2a,LANG_MENU_RAW_DEVELOP,                MENUITEM_PROC,      gui_raw_develop, 0 ),
1909     MENU_ENUM2  (0x5c,LANG_MENU_BAD_PIXEL_REMOVAL,          &conf.bad_pixel_removal, gui_bad_pixel_removal_modes ),
1910     MENU_ITEM   (0x5c,LANG_MENU_RAW_CACHED,                 MENUITEM_BOOL,      &conf.raw_cache,            0 ),
1911 #ifdef OPT_DEBUGGING
1912     MENU_ITEM   (0x5c,LANG_MENU_RAW_TIMER,                  MENUITEM_BOOL,      &conf.raw_timer,            0 ),
1913 #endif
1914     MENU_ITEM   (0x0 ,(int)"DNG",                           MENUITEM_SEPARATOR, 0,                                                      0 ),
1915     MENU_ITEM   (0x5c,LANG_MENU_DNG_FORMAT,                 MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_raw , (int)cb_change_dng ),
1916     MENU_ITEM   (0x5c,LANG_MENU_RAW_DNG_EXT,                MENUITEM_BOOL,      &conf.raw_dng_ext, 0 ),
1917     MENU_ITEM   (0x5f,LANG_MENU_DNG_VERSION,                MENUITEM_ENUM,      gui_dng_version, 0),
1918     MENU_ITEM   (0x5f,LANG_MENU_DNG_CROP_SIZE,              MENUITEM_ENUM,      gui_dng_crop_size, 0),
1919     MENU_ITEM   (0x2a,LANG_MENU_BADPIXEL_CREATE,            MENUITEM_PROC,      gui_menuproc_badpixel_create, 0 ),
1920 #if defined (DNG_EXT_FROM)
1921     MENU_ITEM   (0x71,LANG_MENU_DNG_VIA_USB,                MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_usb_ext , (int)cb_change_dng_usb_ext ),
1922 #endif
1923     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1924     {0}
1925 };
1926 
1927 static CMenu raw_submenu = {0x24,LANG_MENU_RAW_TITLE, raw_submenu_items };
1928 
1929 //-------------------------------------------------------------------
1930 
1931 void cb_zebra_restore_screen()
1932 {
1933     if (!conf.zebra_restore_screen)
1934         conf.zebra_restore_osd = 0;
1935 }
1936 
1937 void cb_zebra_restore_osd()
1938 {
1939     if (conf.zebra_restore_osd)
1940         conf.zebra_restore_screen = 1;
1941 }
1942 
1943 static const char* gui_zebra_mode_modes[] = { "Blink 1", "Blink 2", "Blink 3", "Solid", "Zebra 1", "Zebra 2" };
1944 static const char* gui_zebra_draw_osd_modes[] = { "Nothing", "Histo", "OSD" };
1945 
1946 static CMenuItem zebra_submenu_items[] = {
1947     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_DRAW,              MENUITEM_BOOL,                            &conf.zebra_draw, 0 ),
1948     MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_MODE,             &conf.zebra_mode, gui_zebra_mode_modes ),
1949     MENU_ITEM(0x58,LANG_MENU_ZEBRA_UNDER,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_under,   MENU_MINMAX(0, 32) ),
1950     MENU_ITEM(0x57,LANG_MENU_ZEBRA_OVER,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_over,    MENU_MINMAX(0, 32) ),
1951     MENU_ITEM(0x28,LANG_MENU_ZEBRA_RESTORE_SCREEN,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_screen,     cb_zebra_restore_screen ),
1952     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_RESTORE_OSD,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_osd,        cb_zebra_restore_osd ),
1953     MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_DRAW_OVER,        &conf.zebra_draw_osd, gui_zebra_draw_osd_modes ),
1954     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_MULTICHANNEL,      MENUITEM_BOOL,                            &conf.zebra_multichannel, 0 ),
1955     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1956     {0}
1957 };
1958 
1959 static CMenu zebra_submenu = {0x26,LANG_MENU_ZEBRA_TITLE, zebra_submenu_items };
1960 
1961 //-------------------------------------------------------------------
1962 
1963 static void gui_draw_lang_selected(const char *fn)
1964 {
1965     if (fn) {
1966         strcpy(conf.lang_file, fn);
1967         lang_load_from_file(conf.lang_file);
1968         gui_menu_init(NULL);
1969     }
1970 }
1971 
1972 static void gui_draw_load_lang(int arg)
1973 {
1974     libfselect->file_select(LANG_STR_SELECT_LANG_FILE, conf.lang_file, "A/CHDK/LANG", gui_draw_lang_selected);
1975 }
1976 
1977 static const char* gui_font_enum(int change, int arg)
1978 {
1979     extern int num_codepages;
1980     extern char* codepage_names[];
1981 
1982     gui_enum_value_change(&conf.font_cp,change,num_codepages);
1983 
1984     if (change != 0) {
1985         font_set(conf.font_cp);
1986         rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1987         gui_menu_init(NULL);
1988     }
1989 
1990     return codepage_names[conf.font_cp];
1991 }
1992 
1993 static void gui_draw_menu_rbf_selected(const char *fn)
1994 {
1995     if (fn) {
1996         strcpy(conf.menu_rbf_file, fn);
1997         rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1998         gui_menu_init(NULL);
1999     }
2000 }
2001 
2002 static void gui_draw_load_menu_rbf(int arg)
2003 {
2004     libfselect->file_select(LANG_STR_SELECT_FONT_FILE, conf.menu_rbf_file, "A/CHDK/FONTS", gui_draw_menu_rbf_selected);
2005 }
2006 
2007 static void gui_draw_symbol_rbf_selected(const char *fn)
2008 {
2009     if (fn) {
2010         strcpy(conf.menu_symbol_rbf_file, fn);
2011         if(!rbf_load_symbol(conf.menu_symbol_rbf_file)) conf.menu_symbol_enable=0;              //AKA
2012         gui_menu_init(NULL);
2013     }
2014 }
2015 
2016 static void gui_draw_load_symbol_rbf(int arg)
2017 {
2018     libfselect->file_select(LANG_STR_SELECT_SYMBOL_FILE, conf.menu_symbol_rbf_file, "A/CHDK/SYMBOLS", gui_draw_symbol_rbf_selected);
2019 }
2020 
2021 static void gui_menuproc_reset_files(int arg)
2022 {
2023     conf.lang_file[0] = 0;
2024     strcpy(conf.menu_symbol_rbf_file,DEFAULT_SYMBOL_FILE);
2025     conf.menu_rbf_file[0] = 0;
2026     conf_save();
2027     gui_mbox_init(LANG_INFORMATION, LANG_MENU_RESTART_CAMERA, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
2028 }
2029 
2030 static const char* gui_text_box_charmap[] = { "Default", "German", "Russian" };
2031 
2032 static CMenuItem menu_font_submenu_items[] = {
2033     MENU_ITEM(0x35,LANG_MENU_VIS_LANG,                MENUITEM_PROC,      gui_draw_load_lang, 0 ),
2034     MENU_ITEM(0x5f,LANG_MENU_VIS_OSD_FONT,            MENUITEM_ENUM,      gui_font_enum, &conf.font_cp ),
2035     MENU_ITEM(0x35,LANG_MENU_VIS_MENU_FONT,           MENUITEM_PROC,      gui_draw_load_menu_rbf, 0 ),
2036     MENU_ITEM(0x64,LANG_MENU_VIS_SYMBOL,              MENUITEM_BOOL,      &conf.menu_symbol_enable, 0 ),
2037     MENU_ITEM(0x35,LANG_MENU_VIS_MENU_SYMBOL_FONT,    MENUITEM_PROC,      gui_draw_load_symbol_rbf, 0 ),
2038     MENU_ENUM2(0x5f,LANG_MENU_VIS_CHARMAP,            &conf.tbox_char_map, gui_text_box_charmap ),
2039     MENU_ITEM(0x80,LANG_MENU_RESET_FILES,             MENUITEM_PROC,      gui_menuproc_reset_files, 0 ),
2040     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
2041     {0}
2042 };
2043 
2044 static CMenu menu_font_submenu = {0x28,LANG_MENU_FONT_SETTINGS, menu_font_submenu_items };
2045 
2046 //-------------------------------------------------------------------
2047 
2048 static const char* gui_user_menu_show_enum(int change, int arg)
2049 {
2050     static const char* modes[]={ "Off", "On", "On Direct" };
2051 
2052     void set_usermenu_state();
2053     set_usermenu_state();
2054 
2055     return gui_change_simple_enum(&conf.user_menu_enable,change,modes,sizeof(modes)/sizeof(modes[0]));
2056 }
2057 
2058 static CMenuItem menu_settings_submenu_items[] = {
2059     MENU_ITEM(0x5f,LANG_MENU_USER_MENU_ENABLE,          MENUITEM_ENUM,          gui_user_menu_show_enum, 0 ),
2060     MENU_ITEM(0x5c,LANG_MENU_USER_MENU_AS_ROOT,     MENUITEM_BOOL,          &conf.user_menu_as_root, 0 ),
2061     MENU_ITEM(0x72,LANG_MENU_USER_MENU_EDIT,        MENUITEM_PROC,          module_run, "useredit.flt" ),
2062     MENU_ITEM(0x81,LANG_MENU_VIS_MENU_CENTER,       MENUITEM_BOOL,              &conf.menu_center, 0 ),
2063     MENU_ITEM(0x81,LANG_MENU_SELECT_FIRST_ENTRY,    MENUITEM_BOOL,              &conf.menu_select_first_entry, 0 ),
2064     MENU_ITEM(0x5c,LANG_MENU_SHOW_ALT_HELP,         MENUITEM_BOOL,          &conf.show_alt_helper, 0 ),
2065     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) ),
2066     MENU_ITEM(0x28,LANG_MENU_FONT_SETTINGS,         MENUITEM_SUBMENU,       &menu_font_submenu, 0 ),
2067     MENU_ITEM(0x51,LANG_MENU_BACK,                  MENUITEM_UP, 0, 0 ),
2068     {0}
2069 };
2070 
2071 static CMenu menu_settings_submenu = {0x28,LANG_MENU_MENU_SETTINGS, menu_settings_submenu_items };
2072 
2073 //-------------------------------------------------------------------
2074 
2075 #if CAM_ADJUSTABLE_ALT_BUTTON
2076 
2077 const char* gui_alt_mode_button_enum(int change, int arg)
2078 {
2079 #if defined(CAM_ALT_BUTTON_NAMES) && defined(CAM_ALT_BUTTON_OPTIONS)
2080     static const char* names[] = CAM_ALT_BUTTON_NAMES;
2081     static const int keys[] = CAM_ALT_BUTTON_OPTIONS;
2082 #else
2083 #error Make sure CAM_ALT_BUTTON_NAMES and CAM_ALT_BUTTON_OPTIONS are defined in platform_camera.h
2084 #endif
2085     int i;
2086 
2087     for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
2088         if (conf.alt_mode_button==keys[i]) {
2089             break;
2090         }
2091     }
2092 
2093     i+=change;
2094     if (i<0)
2095         i=(sizeof(names)/sizeof(names[0]))-1;
2096     else if (i>=(sizeof(names)/sizeof(names[0])))
2097         i=0;
2098 
2099     conf.alt_mode_button = keys[i];
2100     return names[i];
2101 }
2102 #endif
2103 
2104 #if CAM_OPTIONAL_EXTRA_BUTTON
2105 static const char* gui_extra_button_enum(int change, int arg)
2106 {
2107 #if defined(CAM_EXTRA_BUTTON_NAMES) && defined(CAM_EXTRA_BUTTON_OPTIONS)
2108     static const char* names[] = CAM_EXTRA_BUTTON_NAMES;
2109     static const int keys[] = CAM_EXTRA_BUTTON_OPTIONS;
2110 #else
2111 #error Make sure CAM_EXTRA_BUTTON_NAMES and CAM_EXTRA_BUTTON_OPTIONS are defined in platform_camera.h
2112 #endif
2113     int i;
2114 
2115     for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
2116         if (conf.extra_button==keys[i]) {
2117             break;
2118         }
2119     }
2120 
2121     i+=change;
2122     if (i<0)
2123         i=(sizeof(names)/sizeof(names[0]))-1;
2124     else if (i>=(sizeof(names)/sizeof(names[0])))
2125         i=0;
2126 
2127     conf.extra_button = keys[i];
2128     kbd_set_extra_button((short)conf.extra_button);
2129     return names[i];
2130 }
2131 #endif //CAM_OPTIONAL_EXTRA_BUTTON
2132 
2133 static const char* gui_raw_toggle_enum(int change, int arg)
2134 {
2135     static const char* raw_toggle[]={ "Off", "On", "On+OSD" };
2136 
2137     gui_enum_value_change(&conf.enable_raw_shortcut,change,sizeof(raw_toggle)/sizeof(raw_toggle[0]));
2138 
2139     return raw_toggle[conf.enable_raw_shortcut];
2140 }
2141 
2142 static const char* gui_alt_power_enum(int change, int arg)
2143 {
2144 // Script option is retained even if scripting is disabled, otherwise conf values will change
2145 // Equivalent to ALT
2146     static const char* modes[]={ "Never", "Alt", "Script", "Always" };
2147 
2148     gui_enum_value_change(&conf.alt_prevent_shutdown,change,sizeof(modes)/sizeof(modes[0]));
2149         
2150     return modes[conf.alt_prevent_shutdown];
2151 }
2152 
2153 static void gui_menuproc_reset_selected(unsigned int btn)
2154 {
2155     if (btn==MBOX_BTN_YES)
2156         conf_load_defaults();
2157 }
2158 
2159 static void gui_menuproc_reset(int arg)
2160 {
2161     gui_mbox_init(LANG_MSG_RESET_OPTIONS_TITLE, 
2162                   LANG_MSG_RESET_OPTIONS_TEXT,
2163                   MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menuproc_reset_selected);
2164 }
2165 
2166 static CMenuItem chdk_settings_menu_items[] = {
2167     MENU_ITEM   (0x22,LANG_MENU_MAIN_OSD_PARAM,             MENUITEM_SUBMENU,   &osd_submenu, 0 ),
2168     MENU_ITEM   (0x72,LANG_MENU_OSD_LAYOUT_EDITOR,          MENUITEM_PROC,      module_run, "_osd_le.flt" ),
2169     MENU_ITEM   (0x28,LANG_MENU_MAIN_VISUAL_PARAM,          MENUITEM_SUBMENU,   &visual_submenu, 0 ),
2170     MENU_ITEM   (0x28,LANG_MENU_MENU_SETTINGS,              MENUITEM_SUBMENU,   &menu_settings_submenu, 0 ),
2171     MENU_ITEM   (0x2f,LANG_MENU_OSD_GRID_PARAMS,            MENUITEM_SUBMENU,   &grid_submenu, 0 ),
2172 #ifdef CAM_HAS_GPS
2173     MENU_ITEM   (0x28,LANG_MENU_GPS,                        MENUITEM_SUBMENU,   &gps_submenu,           0 ),
2174 #endif
2175 #if CAM_REMOTE
2176     MENU_ITEM   (0x86,LANG_MENU_REMOTE_PARAM,               MENUITEM_SUBMENU,   &remote_submenu, 0 ),
2177 #endif
2178     MENU_ITEM   (0x5c,LANG_MENU_MISC_ENABLE_SHORTCUTS,      MENUITEM_BOOL,      &conf.enable_shortcuts, 0 ),
2179     MENU_ITEM   (0x5c,LANG_MENU_MISC_ENABLE_RAW_SHORTCUT,   MENUITEM_ENUM,      gui_raw_toggle_enum, 0 ),
2180     MENU_ITEM   (0x5c,LANG_MENU_MISC_SHOW_SPLASH,           MENUITEM_BOOL,      &conf.splash_show, 0 ),
2181     MENU_ITEM   (0x5c,LANG_MENU_MISC_START_SOUND,           MENUITEM_BOOL,      &conf.start_sound, 0 ),
2182 #if CAM_USE_ZOOM_FOR_MF
2183     MENU_ITEM   (0x59,LANG_MENU_MISC_ZOOM_FOR_MF,           MENUITEM_BOOL,      &conf.use_zoom_mf, 0 ),
2184 #endif
2185 #if CAM_ADJUSTABLE_ALT_BUTTON
2186     MENU_ITEM   (0x22,LANG_MENU_MISC_ALT_BUTTON,            MENUITEM_ENUM,      gui_alt_mode_button_enum, 0 ),
2187 #endif
2188 #if CAM_OPTIONAL_EXTRA_BUTTON
2189     MENU_ITEM   (0x22,LANG_MENU_MISC_EXTRA_BUTTON,          MENUITEM_ENUM,      gui_extra_button_enum, 0 ),
2190 #endif
2191 #if defined(CAM_ZOOM_ASSIST_BUTTON_CONTROL)
2192     MENU_ITEM   (0x5c,LANG_MENU_MISC_ZOOM_ASSIST,           MENUITEM_BOOL,      &conf.zoom_assist_button_disable, 0 ),
2193 #endif
2194     MENU_ITEM   (0x5d,LANG_MENU_MISC_DISABLE_LCD_OFF,       MENUITEM_ENUM,      gui_alt_power_enum, 0 ),
2195     MENU_ITEM   (0x2b,LANG_MENU_MAIN_RESET_OPTIONS,         MENUITEM_PROC,      gui_menuproc_reset, 0 ),
2196     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0, 0 ),
2197     {0}
2198 };
2199 
2200 CMenu chdk_settings_menu = {0x20,LANG_MENU_CHDK_SETTINGS, chdk_settings_menu_items };
2201 
2202 //-------------------------------------------------------------------
2203 
2204 extern CMenu script_submenu;
2205 
2206 static CMenuItem root_menu_items[] = {
2207     MENU_ITEM   (0x21,LANG_MENU_OPERATION_PARAM,            MENUITEM_SUBMENU,   &operation_submenu, 0 ),
2208     MENU_ITEM   (0x23,LANG_MENU_VIDEO_PARAM,                MENUITEM_SUBMENU,   &video_submenu,     0 ),
2209     MENU_ITEM   (0x24,LANG_MENU_MAIN_RAW_PARAM,             MENUITEM_SUBMENU,   &raw_submenu,       0 ),
2210     MENU_ITEM   (0x7f,LANG_MENU_EDGE_OVERLAY,               MENUITEM_SUBMENU,   &edge_overlay_submenu, 0 ),
2211     MENU_ITEM   (0x25,LANG_MENU_MAIN_HISTO_PARAM,           MENUITEM_SUBMENU,   &histo_submenu, 0 ),
2212     MENU_ITEM   (0x26,LANG_MENU_MAIN_ZEBRA_PARAM,           MENUITEM_SUBMENU,   &zebra_submenu,     0 ),
2213     MENU_ITEM   (0x27,LANG_MENU_MAIN_SCRIPT_PARAM,          MENUITEM_SUBMENU,   &script_submenu,    0 ),
2214     MENU_ITEM   (0x22,LANG_MENU_CHDK_SETTINGS,              MENUITEM_SUBMENU,   &chdk_settings_menu, 0 ),
2215     MENU_ITEM   (0x29,LANG_MENU_MAIN_MISC,                  MENUITEM_SUBMENU,   &misc_submenu,      0 ),
2216     MENU_ITEM   (0x2e,LANG_MENU_USER_MENU,                  MENUITEM_SUBMENU,   &user_submenu, 0 ),
2217     {0}
2218 };
2219 
2220 CMenu root_menu = {0x20,LANG_MENU_MAIN_TITLE, root_menu_items };
2221 
2222 // Set visibility of User Menu in root menu based on user menu state
2223 // Note this hack requires the User Menu entry to be the last one in the root_menu_items array above. 
2224 void set_usermenu_state()
2225 {
2226     int i; 
2227     for (i=0; root_menu_items[i].symbol != 0; i++) 
2228     { 
2229         if (root_menu_items[i].value == (int*)&user_submenu) 
2230         { 
2231             if (conf.user_menu_enable) 
2232                 root_menu_items[i].text = LANG_MENU_USER_MENU;  // Enable user menu option in root menu 
2233             else 
2234                 root_menu_items[i].text = 0;                    // Disable user menu option in root menu 
2235             return; 
2236         } 
2237     } 
2238 }
2239 
2240 //-------------------------------------------------------------------
2241 
2242 const char* gui_on_off_enum(int change, int *conf_val)
2243 {
2244     static const char* modes[]={ "Off", "On"};
2245     return gui_change_simple_enum(conf_val,change,modes,sizeof(modes)/sizeof(modes[0]));
2246 }
2247 
2248 #ifdef  CAM_TOUCHSCREEN_UI
2249 
2250 const char* gui_override_disable_enum(int change, int arg)
2251 {
2252     return gui_change_simple_enum(&conf.override_disable,change,gui_override_disable_modes,sizeof(gui_override_disable_modes)/sizeof(gui_override_disable_modes[0]));
2253 }
2254 
2255 const char* gui_nd_filter_state_enum(int change, int arg)
2256 {
2257     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]));
2258 }
2259 
2260 const char* gui_histo_show_enum(int change, int arg)
2261 {
2262     return gui_change_simple_enum(&conf.show_histo,change,gui_histo_show_modes,sizeof(gui_histo_show_modes)/sizeof(gui_histo_show_modes[0]));
2263 }
2264 
2265 #endif
2266 
2267 //-------------------------------------------------------------------
2268 // Splash screen handling
2269 
2270 
2271 #if defined(VER_CHDK)
2272 #define LOGO_WIDTH  149
2273 #define LOGO_HEIGHT 84
2274 #else
2275 #define LOGO_WIDTH  169
2276 #define LOGO_HEIGHT 74
2277 #endif
2278 
2279 static int gui_splash;
2280 static char *logo = NULL;
2281 static int logo_size, logo_text_width, logo_text_height;
2282 
2283 static void init_splash()
2284 {
2285     int i = 0, index = 0;
2286     while (index < sizeof(text_raw))
2287     {
2288         text[i++] = &text_raw[index];
2289         while (text_raw[index++]) ;
2290     }
2291 
2292     gui_splash = (conf.splash_show) ? SPLASH_TIME : 0;
2293 
2294     if (gui_splash)
2295     {
2296 #if defined(VER_CHDK)
2297         const char *logo_name="A/CHDK/DATA/logo.dat";
2298 #else   // CHDK-DE
2299         const char *logo_name="A/CHDK/DATA/logo_de.dat";
2300 #endif
2301         logo = load_file(logo_name, &logo_size, 0);
2302 
2303         logo_text_height = TEXT_COUNT - 1;
2304         logo_text_width = 0;
2305 
2306         int i;
2307         for (i=0; i<logo_text_height; ++i)
2308         {
2309             int l = strlen(text[i]);
2310             if (l > logo_text_width) logo_text_width = l;
2311         }
2312 
2313         logo_text_width = logo_text_width * FONT_WIDTH + 10;
2314         logo_text_height = logo_text_height * FONT_HEIGHT + 8;
2315     }
2316 }
2317 
2318 static void gui_draw_splash()
2319 {
2320     coord x, y;
2321     int i;
2322     twoColors cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
2323 
2324     const color logo_colors[8] =
2325     {
2326         COLOR_BLACK,
2327         COLOR_RED_DK,
2328         COLOR_RED,
2329         COLOR_GREY,
2330         COLOR_GREY_LT,
2331         COLOR_RED_LT,
2332         COLOR_TRANSPARENT,
2333         COLOR_WHITE
2334     };
2335 
2336     x = (camera_screen.width-logo_text_width)>>1; 
2337     y = ((camera_screen.height-logo_text_height)>>1) + 20;
2338 
2339     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);
2340     for (i=0; i<TEXT_COUNT-1; ++i)
2341     {
2342         draw_string(x+((logo_text_width-strlen(text[i])*FONT_WIDTH)>>1), y+i*FONT_HEIGHT+4, text[i], cl);
2343     }
2344 
2345 #if OPT_EXPIRE_TEST
2346     do_expire_splash(x+((logo_text_width)>>1),y+(i+1)*FONT_HEIGHT+4);
2347 #endif
2348 
2349     if (logo)
2350     {
2351         int pos;
2352         int mx = 0;
2353         int my = 0;
2354         int offset_x = (camera_screen.width-LOGO_WIDTH)>>1;
2355 #ifdef THUMB_FW
2356         int offset_y = ((camera_screen.height-LOGO_HEIGHT)>>1) - 66 ;
2357 #else
2358         int offset_y = ((camera_screen.height-LOGO_HEIGHT)>>1) - 42 ;
2359 #endif
2360         for (pos=0; pos<logo_size; pos++)
2361         {
2362             char data = logo[pos];
2363             color c = logo_colors[(data>>5) & 0x07];
2364             for (i=0; i<(data&0x1F)+1; i++)
2365             {
2366                 if (c!=0x00)
2367                 {
2368                     draw_pixel(offset_x+mx,offset_y+my,c);
2369                 }
2370                 if (mx == LOGO_WIDTH)
2371                 {
2372                     mx = 0;
2373                     my++;
2374                 }
2375                 else
2376                 {
2377                     mx++;
2378                 }     
2379             }
2380         }
2381     }
2382 }
2383 
2384 static void gui_handle_splash(int force_redraw)
2385 {
2386     if (gui_splash)
2387     {
2388         if (camera_info.state.gui_mode_none || camera_info.state.gui_mode_alt)
2389             if (force_redraw || (gui_splash == SPLASH_TIME))
2390                 gui_draw_splash();
2391 
2392         if (--gui_splash == 0)
2393         {
2394             if (camera_info.state.gui_mode_none || camera_info.state.gui_mode_alt)
2395                 gui_set_need_restore();
2396             if (logo)
2397                 free(logo);
2398             logo = NULL;
2399         }
2400     }
2401 }
2402 
2403 //-------------------------------------------------------------------
2404 static gui_handler *gui_mode=0; // current gui mode. pointer to gui_handler structure
2405 
2406 static int gui_osd_need_restore = 0;    // Set when screen needs to be erase and redrawn
2407 static int gui_mode_need_redraw = 0;    // Set if current mode needs to redraw itself
2408 
2409 //-------------------------------------------------------------------
2410 
2411 void gui_set_need_restore()
2412 {
2413     gui_osd_need_restore = 1;
2414 }
2415 
2416 void gui_cancel_need_restore()
2417 {
2418     gui_osd_need_restore = 0;
2419     gui_mode_need_redraw = 0;
2420 }
2421 
2422 void gui_set_need_redraw()
2423 {
2424     gui_mode_need_redraw = 1;
2425 }
2426 
2427 //-------------------------------------------------------------------
2428 void gui_init()
2429 {
2430     gui_set_mode(&defaultGuiHandler);
2431     if (conf.start_sound > 0)
2432     {
2433         play_sound(4);
2434     }
2435 
2436     init_splash();
2437 
2438     draw_init();
2439 
2440     process_file( "A/CHDK/badpixel", make_pixel_list, 1 );
2441     process_file( "A/CHDK/badpixel.txt", make_pixel_list, 1 );
2442 }
2443 
2444 //-------------------------------------------------------------------
2445 gui_mode_t gui_get_mode() { return gui_mode->mode; }
2446 
2447 //-------------------------------------------------------------------
2448 // Set new GUI mode, returns old mode
2449 gui_handler* gui_set_mode(gui_handler *mode) 
2450 {
2451     // Set up gui mode & state variables
2452     camera_info.state.gui_mode = mode->mode;
2453     camera_info.state.gui_mode_none = (camera_info.state.gui_mode == GUI_MODE_NONE);
2454     camera_info.state.gui_mode_alt = (camera_info.state.gui_mode == GUI_MODE_ALT);
2455         
2456         if ( gui_mode == mode )
2457                 return gui_mode;
2458 
2459 #ifdef CAM_TOUCHSCREEN_UI
2460     if (((gui_mode->mode == GUI_MODE_NONE) != (mode->mode == GUI_MODE_NONE)) || // Change from GUI_MODE_NONE to any other or vice-versa
2461         ((gui_mode->mode >  GUI_MODE_MENU) != (mode->mode >  GUI_MODE_MENU)))   // Switch in & out of menu mode
2462         redraw_buttons = 1;
2463 #endif
2464 
2465     set_usermenu_state();
2466 
2467     gui_handler *old_mode = gui_mode;
2468     gui_mode = mode;
2469 
2470     gui_osd_need_restore = 0;
2471 
2472     // Flag for screen erase/redraw unless mode is marked not to (e.g. menu box popup)
2473     if (((gui_mode->flags & (GUI_MODE_FLAG_NODRAWRESTORE|GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) == 0) &&
2474         ((old_mode->flags & GUI_MODE_FLAG_NORESTORE_ON_SWITCH) == 0))
2475         gui_set_need_restore();
2476     // 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)
2477     if ((old_mode->flags & (GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) != 0)
2478         gui_set_need_redraw();
2479 
2480 #ifdef CAM_DISP_ALT_TEXT
2481     if (camera_info.state.gui_mode_alt)
2482         gui_reset_alt_helper();
2483 #endif
2484 
2485     return old_mode;
2486 }
2487 
2488 //-------------------------------------------------------------------
2489 
2490 #ifdef CAM_DISP_ALT_TEXT
2491 
2492 static int is_menu_shortcut = 0;
2493 
2494 static char* gui_shortcut_text(int button)
2495 {
2496     switch (button)
2497     {
2498     case KEY_DISPLAY:
2499         return CAM_DISP_BUTTON_NAME;
2500     case KEY_UP:
2501         return "UP";
2502     case KEY_DOWN:
2503         return "DOWN";
2504     case KEY_LEFT:
2505         return "LEFT";
2506     case KEY_RIGHT:
2507         return "RIGHT";
2508     case KEY_ERASE:
2509         return "ERASE";
2510     case KEY_MENU:
2511         is_menu_shortcut = 1;
2512         return "MENU*";
2513     case KEY_VIDEO:
2514         return "VIDEO";
2515     default:
2516         return "?";
2517     }
2518 }
2519 
2520 static int shortcut_text(int x, int y, int button, int func_str, const char *state, twoColors col)
2521 {
2522     buf[0] = 0;
2523     if (state)
2524     {
2525         sprintf(buf,"%-5s %20s",gui_shortcut_text(button),lang_str(func_str));
2526         buf[26] = 0;
2527         sprintf(buf+strlen(buf)," [%6s",state);
2528         buf[34] = 0;
2529         strcat(buf,"]");
2530     }
2531     else if (button)
2532     {
2533         sprintf(buf,"%-5s %29s",gui_shortcut_text(button),lang_str(func_str));
2534     }
2535     else
2536     {
2537         sprintf(buf,"%-35s",lang_str(func_str));
2538     }
2539     buf[35] = 0;
2540     draw_string(x, y, buf, col);
2541     return y + FONT_HEIGHT;
2542 }
2543 
2544 static int gui_helper_displayat = 0;
2545 
2546 void gui_reset_alt_helper()
2547 {
2548     gui_helper_displayat = get_tick_count() + (conf.show_alt_helper_delay * 1000);
2549 }
2550 
2551 static void gui_draw_alt_helper()
2552 {
2553     if ((camera_info.state.state_kbd_script_run != 0) || (console_displayed != 0))
2554     {
2555         if (gui_helper_displayat <= get_tick_count())
2556             gui_set_need_restore();
2557         gui_reset_alt_helper();
2558     }
2559 
2560     if ((conf.show_alt_helper == 0) || (gui_helper_displayat > get_tick_count()))
2561     {
2562         gui_draw_osd();
2563         return;
2564     }
2565 
2566     is_menu_shortcut = 0;
2567 
2568     int y = FONT_HEIGHT;
2569     int x = ((camera_screen.width/2)-(FONT_WIDTH*35/2));
2570 
2571     twoColors col = user_color(conf.menu_color);
2572     twoColors hdr_col = user_color(conf.menu_title_color);
2573 
2574     sprintf(buf,lang_str(LANG_HELP_HEADER),
2575             lang_str(LANG_HELP_ALT_SHORTCUTS),
2576             (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_USER_MENU):lang_str(LANG_HELP_CHDK_MENU)); 
2577     buf[35] = 0;
2578     draw_string(x, y, buf, hdr_col);
2579     y += FONT_HEIGHT;
2580 
2581     if (conf.user_menu_enable)
2582     {
2583         sprintf(buf,lang_str(LANG_HELP_HEADER),
2584                 lang_str(LANG_HELP_HALF_PRESS),
2585                 (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_CHDK_MENU):lang_str(LANG_HELP_USER_MENU)); 
2586         buf[35] = 0;
2587         draw_string(x, y, buf, col);
2588         y += FONT_HEIGHT;
2589     }
2590 
2591     draw_string(x, y, lang_str(LANG_HELP_SCRIPTS), col);
2592     y += FONT_HEIGHT;
2593 
2594 #if !defined(CAM_HAS_MANUAL_FOCUS) && defined(SHORTCUT_MF_TOGGLE)
2595     y = shortcut_text(x, y, SHORTCUT_MF_TOGGLE,LANG_HELP_MANUAL_FOCUS,gui_on_off_enum(0,&conf.subj_dist_override_koef), col);
2596 #endif
2597 
2598     if (shooting_get_common_focus_mode())           // Check in manual focus mode
2599     {
2600         sprintf(buf,lang_str(LANG_HELP_FOCUS),gui_shortcut_text(SHORTCUT_SET_INFINITY),gui_shortcut_text(SHORTCUT_SET_HYPERFOCAL));
2601         draw_string(x, y, buf, col);
2602         y += FONT_HEIGHT;
2603     }
2604 
2605 #if !CAM_HAS_ERASE_BUTTON
2606 #ifdef OPT_DEBUGGING
2607     if (conf.debug_shortcut_action)
2608         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], col);
2609     else
2610 #endif
2611     if (shooting_get_common_focus_mode())           // Check in manual focus mode
2612     {
2613 #if CAM_HAS_ZOOM_LEVER
2614         if (SHORTCUT_TOGGLE_RAW != SHORTCUT_SET_INFINITY)
2615             y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_INF_FOCUS, 0, col);
2616 #else
2617         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_CHG_FOCUS_FACTOR, 0, col);
2618 #endif
2619     }
2620     else
2621         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), col);
2622 #else
2623 #ifdef OPT_DEBUGGING
2624     if (conf.debug_shortcut_action)
2625         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], col);
2626     else
2627 #endif
2628         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), col);
2629 #endif
2630 
2631     y = shortcut_text(x, y, 0 ,LANG_HELP_HALF_PRESS, 0, hdr_col);
2632 
2633     if ( conf.enable_shortcuts)
2634     {
2635         y = shortcut_text(x, y, SHORTCUT_DISABLE_OVERRIDES,LANG_MENU_OVERRIDE_DISABLE,gui_override_disable_modes[conf.override_disable], col);
2636         y = shortcut_text(x, y, SHORTCUT_TOGGLE_HISTO,LANG_MENU_HISTO_SHOW,gui_histo_show_modes[conf.show_histo], col);
2637         y = shortcut_text(x, y, SHORTCUT_TOGGLE_ZEBRA,LANG_MENU_ZEBRA_DRAW,gui_on_off_enum(0,&conf.zebra_draw), col);
2638         y = shortcut_text(x, y, SHORTCUT_TOGGLE_OSD,LANG_MENU_OSD_SHOW,gui_on_off_enum(0,&conf.show_osd), col);
2639     }
2640     else
2641     {
2642         y = shortcut_text(x, y, 0,LANG_HELP_SHORTCUTS_DISABLED, 0, col);
2643     }
2644 
2645     if (conf.hide_osd == 0)
2646         y = shortcut_text(x, y, KEY_DISPLAY, LANG_HELP_HIDE_OSD, 0, col);
2647 
2648     if (is_menu_shortcut)
2649         y = shortcut_text(x, y, 0 ,LANG_HELP_NOT_ALT, 0, col);
2650 }
2651 
2652 #endif
2653 
2654 //-------------------------------------------------------------------
2655 
2656 void gui_chdk_draw(int force_redraw)
2657 {
2658     static int clear_for_title = 1;
2659 
2660 #ifdef CAM_DISP_ALT_TEXT
2661     gui_draw_alt_helper();
2662 #else
2663     gui_draw_osd();
2664 #endif
2665 
2666     if (camera_info.state.osd_title_line) 
2667     {
2668         int w = camera_screen.disp_width;
2669 #ifdef CAM_DISP_ALT_TEXT
2670         script_get_alt_text(buf);
2671         w = draw_string_justified(camera_screen.disp_left, camera_screen.height-FONT_HEIGHT,
2672                                   buf, MAKE_COLOR(COLOR_RED, COLOR_WHITE), 0, w, TEXT_CENTER) - camera_screen.disp_left;
2673 #endif     
2674 
2675         if (camera_info.state.mode_rec || camera_info.state.mode_play)
2676         {
2677             // Draw script title (up to <ALT> text, if shown)
2678             draw_string_clipped(camera_screen.disp_left, camera_screen.height-FONT_HEIGHT, script_title, user_color(conf.menu_color), w);
2679         }
2680         clear_for_title = 1;   
2681     }
2682     else if (clear_for_title)
2683     {
2684         clear_for_title = 0;
2685     }
2686 
2687     console_draw(force_redraw);
2688 }
2689 
2690 //-------------------------------------------------------------------
2691 static void gui_debug_shortcut(void) 
2692 {
2693 #ifdef OPT_DEBUGGING
2694     static int lastcall = -1;
2695     int t=get_tick_count();
2696     if ( lastcall != -1) {
2697         if (t-lastcall <= 400)
2698             debug_display_direction = -debug_display_direction;
2699     }
2700     lastcall=t;
2701     switch(conf.debug_shortcut_action) {
2702             case 1:
2703                 schedule_memdump();
2704                 break;
2705             case 2:
2706                 gui_update_debug_page();
2707                 break;
2708             case 3:
2709                 gui_compare_props(0); // compare properties
2710                 break;
2711             case 4:
2712                 gui_compare_props(1); // compare UI properties
2713                 break;
2714     }
2715 #endif
2716 }
2717 
2718 //-------------------------------------------------------------------
2719 // Handler for Menu button press default - enter Menu mode
2720 void gui_default_kbd_process_menu_btn()
2721 {
2722     gui_set_mode(&menuGuiHandler);
2723 }
2724 
2725 // Change SD override factor, direction = 1 to increase, -1 to decrease
2726 // Only applies if camera has a Zoom lever
2727 #if CAM_HAS_ZOOM_LEVER
2728 static void sd_override_koef(int direction)
2729 {
2730     if (direction > 0)
2731     {
2732         if (conf.subj_dist_override_koef==SD_OVERRIDE_OFF)
2733         {
2734             conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2735             menu_set_increment_factor(1);
2736         }
2737         else if (menu_get_increment_factor() < menu_calc_max_increment_factor(CAMERA_MAX_DIST))
2738         {
2739             menu_set_increment_factor(menu_get_increment_factor() * 10);
2740         }
2741         else
2742         {
2743             conf.subj_dist_override_koef = SD_OVERRIDE_INFINITY;
2744         }
2745     }
2746     else if (direction < 0)
2747     {
2748         if (conf.subj_dist_override_koef==SD_OVERRIDE_INFINITY)
2749         {
2750             conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2751             menu_set_increment_factor(menu_calc_max_increment_factor(CAMERA_MAX_DIST));
2752         }
2753         else if (menu_get_increment_factor() > 1)
2754         {
2755             menu_set_increment_factor(menu_get_increment_factor() / 10);
2756         }
2757         else
2758         {
2759             conf.subj_dist_override_koef = SD_OVERRIDE_OFF;
2760         }
2761     }
2762     shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2763 }
2764 #endif
2765 
2766 // Change SD override by factor amount, direction = 1 to increase (zoom in), -1 to decrease (zoom out)
2767 static void sd_override(int direction)
2768 {
2769     if (conf.subj_dist_override_koef == SD_OVERRIDE_ON)
2770     {
2771         gui_subj_dist_override_value_enum(direction*menu_get_increment_factor(),0);
2772         shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
2773     }
2774 }
2775 
2776 static int alt_mode_script_run()
2777 {
2778     int remote_script_start_ready = 0;
2779 
2780     // 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
2781     if (conf.remote_enable && conf.remote_enable_scripts && get_usb_power(SINGLE_PULSE) > 5)
2782         remote_script_start_ready=1;
2783 
2784     // Start a script if the shutter button pressed in <ALT> mode (kdb_blocked) or USB remote sequence not running
2785     //  or if script start on <ALT> enabled and this is the first pass through <ALT> mode
2786     if ( kbd_is_key_clicked(KEY_SHOOT_FULL) || remote_script_start_ready || script_run_on_alt_flag ) 
2787     {
2788         script_run_on_alt_flag = 0 ;
2789         script_start_gui(0);
2790         return 1;
2791     }
2792 
2793     return 0;
2794 }
2795 
2796 // Main button processing for CHDK Alt mode (not in MENU mode)
2797 // This needs to be cleaned up, re-organised and commented !!!!
2798 int gui_chdk_kbd_process()
2799 {
2800     if (alt_mode_script_run()) return 0;
2801 
2802     // Process Shutter Half Press + BUTTON shortcuts
2803     gui_kbd_shortcuts();
2804     if (camera_info.state.is_shutter_half_press) return 0;
2805 
2806     int reset_helper = 0;
2807 
2808 #if !CAM_HAS_ERASE_BUTTON                              // ALT RAW toggle kbd processing if camera has SD override but no erase button
2809     if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2810     {
2811         if (conf.debug_shortcut_action > 0)
2812         {
2813             gui_debug_shortcut();
2814         }
2815         // Check in manual focus mode
2816         else if (!shooting_get_common_focus_mode())
2817         {
2818             // Not manual focus mode so just update RAW save setting
2819             cb_change_save_raw();
2820         }
2821         else
2822         {
2823             // In manual focus mode so update shooting distance
2824 #if CAM_HAS_ZOOM_LEVER
2825             conf.subj_dist_override_value=CAMERA_MAX_DIST;
2826             shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2827 #else
2828             gui_subj_dist_override_koef_enum(1,0);
2829 #endif
2830             reset_helper = 1;
2831         }
2832     }
2833 #else                                                   // ALT RAW toggle kbd processing if can't SD override or has erase button
2834     if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2835     {
2836         if (conf.debug_shortcut_action > 0)
2837         {
2838             gui_debug_shortcut();
2839         }
2840         else
2841         {
2842             // Change RAW save state
2843             cb_change_save_raw();
2844         }
2845     }
2846 #endif
2847     else if (kbd_is_key_clicked(KEY_SET))
2848     {
2849         gui_menu_init(&script_submenu);
2850         gui_default_kbd_process_menu_btn();
2851     }
2852     else
2853     {
2854 #if !CAM_HAS_MANUAL_FOCUS
2855         if (kbd_is_key_clicked(SHORTCUT_MF_TOGGLE))     // Camera does not have manual focus
2856         {
2857             if (conf.subj_dist_override_koef>SD_OVERRIDE_OFF)
2858                 conf.subj_dist_override_koef=SD_OVERRIDE_OFF;
2859             else conf.subj_dist_override_koef=SD_OVERRIDE_ON;
2860             reset_helper = 1;
2861         }
2862         else
2863 #endif
2864         if (shooting_get_common_focus_mode())           // Check in manual focus mode
2865         {
2866 #if CAM_HAS_ZOOM_LEVER                                  // Camera has zoom lever, use left & right to change factor,up to set infinity
2867             if (kbd_is_key_clicked(KEY_RIGHT))
2868             {
2869                 sd_override_koef(1);
2870                 reset_helper = 1;
2871             }
2872             else if (kbd_is_key_clicked(KEY_LEFT))
2873             {
2874                 sd_override_koef(-1);
2875                 reset_helper = 1;
2876             }
2877             else if (kbd_is_key_clicked(SHORTCUT_SET_INFINITY))
2878             {
2879                 conf.subj_dist_override_value=CAMERA_MAX_DIST;
2880                 shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2881                 reset_helper = 1;
2882             }
2883             else
2884 #endif
2885             if (kbd_is_key_clicked(SHORTCUT_SET_HYPERFOCAL))    // Set hyperfocal distance if down pressed
2886             {
2887                 if ((camera_info.state.mode_shooting==MODE_M) || (camera_info.state.mode_shooting==MODE_AV))
2888                     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;
2889                 else conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance();
2890                 shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2891                 reset_helper = 1;
2892             }
2893             else
2894             {
2895                 switch (kbd_get_autoclicked_key())
2896                 {
2897 #if CAM_HAS_ZOOM_LEVER
2898                 case KEY_ZOOM_IN:
2899 #else
2900                 case KEY_RIGHT:
2901 #endif
2902                     sd_override(1);
2903                     reset_helper = 1;
2904                     break;
2905 #if CAM_HAS_ZOOM_LEVER
2906                 case KEY_ZOOM_OUT:
2907 #else
2908                 case KEY_LEFT:
2909 #endif
2910                     sd_override(-1);
2911                     reset_helper = 1;
2912                     break;
2913                 }
2914             }
2915         }
2916     }
2917 
2918     if (reset_helper)
2919     {
2920         gui_set_need_restore();
2921 #ifdef CAM_DISP_ALT_TEXT
2922         gui_reset_alt_helper();
2923 #endif
2924     }
2925 
2926     return 0;
2927 }
2928 
2929 //-------------------------------------------------------------------
2930 extern int no_modules_flag;
2931 void gui_draw_no_module_warning()
2932 {
2933     if ( no_modules_flag == 1 ) {
2934         draw_string(FONT_WIDTH, FONT_HEIGHT, lang_str(LANG_ERROR_MISSING_MODULES), user_color(conf.osd_color_warn));
2935     }
2936 }
2937 
2938 //-------------------------------------------------------------------
2939 // Handler for Menu button press in CHDK Alt mode (not in Menu mode)
2940 // Enter main menu or user menu based on configuration
2941 void gui_chdk_kbd_process_menu_btn()
2942 {
2943     if (conf.user_menu_enable &&
2944         ((conf.user_menu_as_root && !camera_info.state.is_shutter_half_press) ||
2945          (!conf.user_menu_as_root && camera_info.state.is_shutter_half_press)))
2946         gui_menu_init(&user_submenu);
2947     else
2948         gui_menu_init(&root_menu);
2949 
2950     gui_default_kbd_process_menu_btn();
2951 }
2952 
2953 //-------------------------------------------------------------------
2954 // GUI handler for <ALT> mode
2955 gui_handler altGuiHandler = { GUI_MODE_ALT, gui_chdk_draw, gui_chdk_kbd_process, gui_chdk_kbd_process_menu_btn, 0, 0, };
2956 
2957 //-------------------------------------------------------------------
2958 // Main GUI redraw function, perform common initialisation then calls the redraw handler for the mode
2959 void gui_redraw(int flag_gui_enforce_redraw)
2960 {
2961     if (!draw_test_guard() && (!camera_info.state.gui_mode_none || gui_splash))     // Attempt to detect screen erase in <Alt> mode, redraw if needed
2962     {
2963         draw_set_guard();
2964         flag_gui_enforce_redraw = 1;
2965 #ifdef CAM_TOUCHSCREEN_UI
2966         redraw_buttons = 1;
2967 #endif
2968     }
2969 
2970 #ifdef CAM_TOUCHSCREEN_UI
2971     extern void virtual_buttons();
2972     virtual_buttons();
2973 #endif
2974 
2975     // Erase screen if needed
2976     if (gui_osd_need_restore)
2977     {
2978         draw_restore();
2979         gui_osd_need_restore = 0;
2980         flag_gui_enforce_redraw = 1;
2981     }
2982 
2983     // Force mode redraw if needed
2984     if (gui_mode_need_redraw)
2985     {
2986         gui_mode_need_redraw = 0;
2987             flag_gui_enforce_redraw = 1;
2988     }
2989 
2990 #ifdef OPT_EXPIRE_TEST
2991     do_expire_check();
2992 #endif
2993 
2994     gui_handle_splash(flag_gui_enforce_redraw);
2995 
2996     // visible warning if modules missing
2997     gui_draw_no_module_warning();
2998 
2999 // DEBUG: uncomment if you want debug values always on top
3000 //gui_draw_debug_vals_osd();
3001 
3002     // Call redraw handler
3003     if (gui_mode->redraw)
3004         gui_mode->redraw(flag_gui_enforce_redraw);
3005 }
3006 
3007 //-------------------------------------------------------------------
3008 // Main kbd processing for GUI modes
3009 // Return:
3010 //          0 = normal
3011 //          1 = block buttons pressed from Camera firmware
3012 int gui_kbd_process()
3013 {
3014     if (gui_mode)
3015     {
3016         // Call menu button handler if menu button pressed
3017         if (gui_mode->kbd_process_menu_btn)
3018         {
3019             if (kbd_is_key_clicked(KEY_MENU))
3020             {
3021                 gui_mode->kbd_process_menu_btn();
3022                 return 0;
3023             }
3024         }
3025 
3026         // Call mode handler for other buttons
3027         if (gui_mode->kbd_process) return gui_mode->kbd_process();
3028     }
3029     return 0;
3030 }
3031 
3032 // Handle touch screen presses
3033 int gui_touch_process(int x, int y)
3034 {
3035     if (gui_mode && gui_mode->touch_handler)
3036         return gui_mode->touch_handler(x, y);
3037     return 0;
3038 }
3039 
3040 //------------------------------------------------------------------- 
3041 static int gui_current_alt_state = ALT_MODE_NORMAL;
3042 
3043 // Called from the KBD task code to change ALT mode state
3044 void gui_set_alt_mode_state(int new_state)
3045 {
3046     gui_current_alt_state = new_state;
3047 }
3048 
3049 // Called from the GUI task code to set the ALT mode state
3050 void gui_activate_alt_mode()
3051 {
3052     extern gui_handler scriptGuiHandler;
3053 
3054     switch (gui_current_alt_state)
3055     {
3056     case ALT_MODE_ENTER:
3057         
3058             if (camera_info.state.state_kbd_script_run)
3059                 gui_set_mode(&scriptGuiHandler);
3060                 else
3061                 gui_set_mode(&altGuiHandler);
3062 
3063         conf_update_prevent_shutdown();
3064         
3065         vid_turn_off_updates();
3066 
3067         // If user menu set to start automatically when <ALT> mode entered 
3068         // then enter user menu mode, unless a script was paused by exiting 
3069         // <ALT> mode when the script was running.
3070             gui_user_menu_flag = 0;
3071             if ((conf.user_menu_enable == 2) && !camera_info.state.state_kbd_script_run) {
3072                     gui_menu_init(&user_submenu);
3073                     gui_set_mode(&menuGuiHandler);
3074                     gui_user_menu_flag = 1;
3075             }
3076         break;
3077 
3078     case ALT_MODE_LEAVE:
3079         conf_save();
3080 
3081         // Unload all modules which are marked as safe to unload, or loaded for menus
3082         module_exit_alt();
3083 
3084         rbf_set_codepage(FONT_CP_WIN);
3085         vid_turn_on_updates();
3086         gui_set_mode(&defaultGuiHandler);
3087 
3088             conf_update_prevent_shutdown();
3089         break;
3090     }
3091 
3092     // Reset to stable state
3093     gui_current_alt_state = ALT_MODE_NORMAL;
3094 }

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