root/core/gui.c

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

DEFINITIONS

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

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

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