This source file includes following definitions.
- find_param
- new_param
- skip_whitespace
- skip_to_token
- skip_token
- skip_toeol
- skip_eol
- skip_tochar
- get_token
- get_name
- get_script_filename
- process_title
- process_subtitle
- check_param
- process_param
- get_default
- process_default
- get_range
- process_range
- get_values
- process_values
- process_single
- script_scan
- make_param_filename
- get_last_paramset_num
- load_params_values
- do_save_param_file
- save_params_values
- script_reset_to_default_params_values
- script_load
- gui_script_param_set_enum
- gui_load_script_selected
- gui_load_script
- gui_reset_script_default
- gui_load_script_default
- cb_change_param_save_enum
- gui_update_script_submenu
1 #include "camera_info.h"
2 #include "conf.h"
3 #include "gui.h"
4 #include "gui_lang.h"
5 #include "gui_menu.h"
6 #include "fileutil.h"
7 #include "ctype.h"
8
9 #include "script_api.h"
10 #include "gui_fselect.h"
11
12
13 static void gui_update_script_submenu();
14
15
16
17 #define SCRIPT_DEFAULT_FILENAME "A/CHDK/SCRIPTS/DEFAULT.LUA"
18 #define SCRIPT_DATA_PATH "A/CHDK/DATA/"
19
20
21 enum FilenameMakeModeEnum {
22 MAKE_PARAMSETNUM_FILENAME,
23 MAKE_PARAM_FILENAME,
24 MAKE_PARAM_FILENAME_V2
25 };
26
27
28
29 char script_title[36];
30 _chdk_version_t script_version;
31 int script_has_version = 0;
32 static int last_script_param_set = -1;
33 static int is_script_loaded = 0;
34
35 #define DEFAULT_PARAM_SET 10
36 #define MAX_PARAM_NAME_LEN 64
37
38 sc_param *script_params = 0;
39 static sc_param *tail = 0;
40 int script_param_count;
41
42
43
44 sc_param* find_param(char *name)
45 {
46 sc_param *p = script_params;
47 while (p)
48 {
49 if ((p->name != 0) && (strcmp(name, p->name) == 0))
50 break;
51 p = p->next;
52 }
53 return p;
54 }
55
56
57 sc_param* new_param(char *name)
58 {
59 sc_param *p = malloc(sizeof(sc_param));
60 memset(p, 0, sizeof(sc_param));
61 if (tail)
62 {
63 tail->next = p;
64 tail = p;
65 }
66 else
67 {
68 script_params = tail = p;
69 }
70 script_param_count++;
71
72 if (name != 0)
73 {
74 p->name = malloc(strlen(name)+1);
75 strcpy(p->name, name);
76 }
77
78 return p;
79 }
80
81
82
83 #define IS_SPACE(p) ((*p == ' ') || (*p == '\t'))
84 #define IS_EOL(p) ((*p == '\n') || (*p == '\r'))
85
86 const char* skip_whitespace(const char* p) { while (IS_SPACE(p)) p++; return p; }
87 const char* skip_to_token(const char* p) { while (IS_SPACE(p) || (*p == '=')) p++; return p; }
88 const char* skip_token(const char* p) { while (*p && !IS_EOL(p) && !IS_SPACE(p) && (*p != '=')) p++; return p; }
89 const char* skip_toeol(const char* p) { while (*p && !IS_EOL(p)) p++; return p; }
90 const char* skip_eol(const char *p) { p = skip_toeol(p); if (*p == '\r') p++; if (*p == '\n') p++; return p; }
91
92 const char* skip_tochar(const char *p, char end)
93 {
94 while (!IS_EOL(p) && (*p != end)) p++;
95 return p;
96 }
97
98
99 const char* get_token(const char *p, char *buf, int maxlen)
100 {
101 p = skip_whitespace(p);
102 int l = skip_token(p) - p;
103 int n = (l <= maxlen) ? l : maxlen;
104 strncpy(buf, p, n);
105 buf[n] = 0;
106 return p + l;
107 }
108
109
110
111
112 const char* get_name(const char *p, int maxlen, sc_param **sp, int create)
113 {
114 char str[MAX_PARAM_NAME_LEN+1];
115 *sp = 0;
116 p = skip_whitespace(p);
117 if (p[0] && isalpha(p[0]))
118 {
119 p = get_token(p, str, maxlen);
120 *sp = find_param(str);
121 if ((*sp == 0) && create)
122 *sp = new_param(str);
123 }
124 return p;
125 }
126
127
128 const char* get_script_filename()
129 {
130 const char* name = 0;
131
132 if (conf.script_file[0] != 0)
133 {
134 name = strrchr(conf.script_file, '/');
135 if (name)
136 name++;
137 else
138 name = conf.script_file;
139 }
140 return name;
141 }
142
143
144
145
146
147
148 static void process_title(const char *ptr)
149 {
150 ptr = skip_whitespace(ptr);
151 int l = skip_toeol(ptr) - ptr;
152 if (l >= (int)sizeof(script_title)) l = sizeof(script_title) - 1;
153 strncpy(script_title, ptr, l);
154 script_title[l] = 0;
155 }
156
157 static void process_subtitle(const char *ptr)
158 {
159 ptr = skip_whitespace(ptr);
160 int l = skip_toeol(ptr) - ptr;
161 if (l >= (int)sizeof(script_title)) l = sizeof(script_title) - 1;
162 sc_param *p = new_param(0);
163 p->desc = malloc(l+1);
164 strncpy(p->desc, ptr, l);
165 p->desc[l] = 0;
166 p->range_type = MENUITEM_SEPARATOR;
167 }
168
169
170
171
172
173
174
175 static int check_param(const char *ptr)
176 {
177 sc_param *p;
178 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, 0);
179 if (p)
180 return 1;
181 return 0;
182 }
183
184
185
186
187
188
189 static void process_param(const char *ptr)
190 {
191 sc_param *p;
192 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, 1);
193 if (p)
194 {
195 ptr = skip_whitespace(ptr);
196 int l = skip_toeol(ptr) - ptr;
197 if (l > MAX_PARAM_NAME_LEN) l = MAX_PARAM_NAME_LEN;
198 p->desc = malloc(l+1);
199 strncpy(p->desc, ptr, l);
200 p->desc[l] = 0;
201 }
202 }
203
204
205
206
207 static const char* get_default(sc_param *p, const char *ptr, int isScript)
208 {
209 ptr = skip_to_token(ptr);
210 if (p)
211 {
212 int type = MENUITEM_INT|MENUITEM_SCRIPT_PARAM;
213 int range = 0;
214 if (strncmp(ptr, "true", 4) == 0)
215 {
216 p->val = 1;
217 type = MENUITEM_BOOL|MENUITEM_SCRIPT_PARAM;
218 range = MENU_MINMAX(1,0);
219
220 }
221 else if (strncmp(ptr, "false", 5) == 0)
222 {
223 p->val = 0;
224 type = MENUITEM_BOOL|MENUITEM_SCRIPT_PARAM;
225 range = MENU_MINMAX(1,0);
226 }
227 else
228 {
229 p->val = strtol(ptr, NULL, 0);
230 }
231 p->old_val = p->val;
232 if (isScript)
233 {
234 p->def_val = p->val;
235 p->range = range;
236 p->range_type = type;
237 }
238 }
239 return skip_token(ptr);
240 }
241
242 static void process_default(const char *ptr, int isScript)
243 {
244 sc_param *p;
245 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, isScript);
246 get_default(p, ptr, isScript);
247 }
248
249
250
251
252 static const char* get_range(sc_param *p, const char *ptr, char end)
253 {
254 ptr = skip_whitespace(ptr);
255 int min = strtol(ptr,NULL,0);
256 ptr = skip_whitespace(skip_token(ptr));
257 int max = strtol(ptr,NULL,0);
258
259 if (p)
260 {
261 p->range = MENU_MINMAX(min,max);
262 p->range_type = MENUITEM_INT|MENUITEM_F_MINMAX|MENUITEM_SCRIPT_PARAM;
263 if ((p->range == MENU_MINMAX(0,1)) || (p->range == MENU_MINMAX(1,0)))
264 p->range_type = MENUITEM_BOOL|MENUITEM_SCRIPT_PARAM;
265 else if ((min >= 0) && (max >= 0))
266 p->range_type |= MENUITEM_F_UNSIGNED;
267 }
268
269 ptr = skip_tochar(ptr, end);
270 if (end && (*ptr == end)) ptr++;
271 return ptr;
272 }
273
274 static void process_range(const char *ptr)
275 {
276 sc_param *p;
277 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, 1);
278 get_range(p, ptr, 0);
279 }
280
281
282
283
284 static const char* get_values(sc_param *p, const char *ptr, char end)
285 {
286 ptr = skip_whitespace(ptr);
287 int len = skip_tochar(ptr, end) - ptr;
288
289 if (p)
290 {
291 p->range = 0;
292 p->range_type = MENUITEM_ENUM2|MENUITEM_SCRIPT_PARAM;
293
294 p->option_buf = malloc(len+1);
295 strncpy(p->option_buf, ptr, len);
296 p->option_buf[len] = 0;
297
298 const char *s = p->option_buf;
299 int cnt = 0;
300 while (*s)
301 {
302 s = skip_whitespace(skip_token(s));
303 cnt++;
304 }
305 p->option_count = cnt;
306 p->options = malloc(cnt * sizeof(char*));
307
308 s = p->option_buf;
309 cnt = 0;
310 while (*s)
311 {
312 p->options[cnt] = s;
313 s = skip_token(s);
314 if (*s)
315 {
316 *((char*)s) = 0;
317 s = skip_whitespace(s+1);
318 }
319 cnt++;
320 }
321 }
322
323 ptr += len;
324 if (end && (*ptr == end)) ptr++;
325 return ptr;
326 }
327
328 static void process_values(const char *ptr)
329 {
330 sc_param *p;
331 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, 1);
332 get_values(p, ptr, 0);
333 }
334
335
336
337
338
339
340 static int process_single(const char *ptr)
341 {
342 sc_param *p;
343 ptr = get_name(ptr, MAX_PARAM_NAME_LEN, &p, 1);
344 if (p)
345 {
346 ptr = get_default(p, ptr, 1);
347 ptr = skip_whitespace(ptr);
348 if ((*ptr == '"') || (*ptr == '\''))
349 {
350 const char *s = skip_tochar(ptr+1, *ptr);
351 p->desc = malloc(s-ptr);
352 strncpy(p->desc, ptr+1, s-ptr-1);
353 p->desc[s-ptr-1] = 0;
354 if (*s == *ptr) s++;
355 ptr = skip_whitespace(s);
356 }
357 else
358 {
359
360 return 0;
361 }
362 if (*ptr == '[')
363 {
364 ptr = get_range(p, ptr+1, ']');
365 }
366 else if (*ptr == '{')
367 {
368 ptr = get_values(p, ptr+1, '}');
369 ptr = skip_whitespace(ptr);
370 if (strncmp(ptr,"table",5) == 0)
371 {
372 p->data_type = DTYPE_TABLE;
373 p->val--;
374 p->def_val--;
375 }
376 }
377 ptr = skip_whitespace(ptr);
378 if (strncmp(ptr,"bool",4) == 0)
379 {
380 p->range = MENU_MINMAX(1,0);
381 p->range_type = MENUITEM_BOOL|MENUITEM_SCRIPT_PARAM;
382 ptr = skip_token(ptr);
383 }
384 ptr = skip_whitespace(ptr);
385 if (strncmp(ptr,"long",4) == 0)
386 {
387 p->range = 9999999;
388 p->range_type = MENUITEM_INT|MENUITEM_SD_INT;
389 ptr = skip_token(ptr);
390 }
391 }
392 return 1;
393 }
394
395
396
397
398
399
400
401
402 static void script_scan()
403 {
404
405 sc_param *p = script_params;
406 while (p)
407 {
408 if (p->name) free(p->name);
409 if (p->desc) free(p->desc);
410 if (p->options) free(p->options);
411 if (p->option_buf) free(p->option_buf);
412 sc_param *l = p;
413 p = p->next;
414 free(l);
415 }
416 script_params = tail = 0;
417 script_param_count = 0;
418
419 parse_version(&script_version, "1.3.0.0", 0);
420 script_has_version = 0;
421 is_script_loaded = 0;
422
423
424 const char *buf=0;
425 if (conf.script_file[0] != 0)
426 buf = load_file_to_length(conf.script_file, 0, 1, 4096);
427
428
429 if (buf == 0)
430 {
431 strcpy(script_title, "NO SCRIPT");
432 return;
433 }
434
435
436 const char *c = get_script_filename();
437 strncpy(script_title, c, sizeof(script_title)-1);
438 script_title[sizeof(script_title)-1]=0;
439
440
441 const char *ptr = buf;
442 while (ptr[0])
443 {
444 ptr = skip_whitespace(ptr);
445 if (ptr[0] == '@')
446 {
447 if (strncmp("@title", ptr, 6)==0)
448 {
449 process_title(ptr+6);
450 }
451 else if (strncmp("@subtitle", ptr, 9)==0)
452 {
453 process_subtitle(ptr+9);
454 }
455 else if (strncmp("@param", ptr, 6)==0)
456 {
457 process_param(ptr+6);
458 }
459 else if (strncmp("@default", ptr, 8)==0)
460 {
461 process_default(ptr+8, 1);
462 }
463 else if (strncmp("@range", ptr, 6)==0)
464 {
465 process_range(ptr+6);
466 }
467 else if (strncmp("@values", ptr, 7)==0)
468 {
469 process_values(ptr+7);
470 }
471 else if (strncmp("@chdk_version", ptr, 13)==0)
472 {
473 ptr = skip_whitespace(ptr+13);
474 parse_version(&script_version, ptr, 0);
475 script_has_version = 1;
476 }
477 }
478 else if (ptr[0] == '#')
479 {
480 process_single(ptr+1);
481 }
482 ptr = skip_eol(ptr);
483 }
484
485 free((void*)buf);
486 is_script_loaded = 1;
487 }
488
489
490
491
492
493
494 static char* make_param_filename(enum FilenameMakeModeEnum mode)
495 {
496
497 static char tgt_buf[100];
498
499
500 const char* name = get_script_filename();
501
502
503 strcpy(tgt_buf, SCRIPT_DATA_PATH);
504
505
506 char* s = tgt_buf + strlen(tgt_buf);
507 strncpy(s, name, 12);
508 s[12] = 0;
509
510
511 s = strrchr(tgt_buf, '.');
512 if (!s) s = tgt_buf + strlen(tgt_buf);
513
514 switch (mode)
515 {
516 case MAKE_PARAMSETNUM_FILENAME:
517 strcpy(s,".cfg");
518 break;
519 case MAKE_PARAM_FILENAME:
520 sprintf(s,"_%d", conf.script_param_set);
521 break;
522 case MAKE_PARAM_FILENAME_V2:
523 sprintf(s,".%d", conf.script_param_set);
524 break;
525 }
526
527 return tgt_buf;
528 }
529
530
531
532
533 static void get_last_paramset_num()
534 {
535
536 if (conf.script_file[0] == 0) return;
537
538 char *nm = make_param_filename(MAKE_PARAMSETNUM_FILENAME);
539 if ( !load_int_value_file( nm, &conf.script_param_set ) )
540 {
541 conf.script_param_set = 0;
542 last_script_param_set = -1;
543 }
544 else
545 {
546 last_script_param_set = conf.script_param_set;
547 }
548 if ((conf.script_param_set < 0) || (conf.script_param_set > 10))
549 conf.script_param_set = 0;
550 }
551
552
553
554
555
556
557
558 static int load_params_values()
559 {
560
561 if (conf.script_file[0] == 0) return 0;
562
563 if (conf.script_param_set == DEFAULT_PARAM_SET) return 0;
564
565 if ((conf.script_param_set < 0) || (conf.script_param_set > 10))
566 conf.script_param_set = 0;
567
568 char *nm = make_param_filename(MAKE_PARAM_FILENAME_V2);
569
570 char* buf = load_file(nm, 0, 1);
571 if (buf == 0)
572 {
573 nm = make_param_filename(MAKE_PARAM_FILENAME);
574 buf = load_file(nm, 0, 1);
575 if (buf == 0)
576 return 0;
577 }
578
579 const char* ptr = buf;
580 int valid = 1;
581
582
583
584
585
586 while (ptr[0] && valid)
587 {
588 ptr = skip_whitespace(ptr);
589 if (ptr[0] == '@')
590 {
591 if (strncmp("@param", ptr, 6) == 0)
592 {
593 if (!check_param(ptr+6))
594 valid = 0;
595 }
596 }
597 else if (ptr[0] == '#')
598 {
599 if (!check_param(ptr+1))
600 valid = 0;
601 }
602 ptr = skip_eol(ptr);
603 }
604
605 if (valid)
606 {
607
608 ptr = buf;
609
610 while (ptr[0])
611 {
612 ptr = skip_whitespace(ptr);
613 if (ptr[0]=='@')
614 {
615
616
617 if (strncmp("@default", ptr, 8)==0)
618 {
619 process_default(ptr+8, 0);
620 }
621 }
622 else if (ptr[0] == '#')
623 {
624 process_default(ptr+1, 0);
625 }
626 ptr = skip_eol(ptr);
627 }
628 }
629
630 free(buf);
631
632 return valid;
633 }
634
635
636
637
638
639
640 static void do_save_param_file()
641 {
642 char buf[100];
643
644 char *fn = make_param_filename(MAKE_PARAM_FILENAME_V2);
645 int fd = open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0777);
646
647 if (fd >= 0)
648 {
649 sc_param *p = script_params;
650 while (p)
651 {
652
653 if (p->name != 0)
654 {
655
656 sprintf(buf,"#%s=%d\n",p->name,p->val);
657 write(fd, buf, strlen(buf));
658 }
659 p = p->next;
660 }
661 close(fd);
662 }
663 }
664
665
666
667
668
669
670
671
672
673
674
675
676
677 void save_params_values( int enforce )
678 {
679 if (conf.script_param_save && (conf.script_param_set != DEFAULT_PARAM_SET))
680 {
681
682 if (conf.script_param_set != last_script_param_set)
683 {
684 char *nm = make_param_filename(MAKE_PARAMSETNUM_FILENAME);
685 save_int_value_file( nm, conf.script_param_set );
686 last_script_param_set = conf.script_param_set;
687 }
688
689 int changed=0;
690
691
692 sc_param *p = script_params;
693 while (p)
694 {
695 if (p->old_val != p->val)
696 {
697 changed++;
698 p->old_val = p->val;
699 }
700 p = p->next;
701 }
702
703 if (enforce || changed)
704 {
705
706 do_save_param_file();
707 }
708 }
709 }
710
711
712
713
714 void script_reset_to_default_params_values()
715 {
716 sc_param *p = script_params;
717 while (p)
718 {
719 p->val = p->def_val;
720 p = p->next;
721 }
722 }
723
724
725
726
727
728
729
730
731
732
733
734 void script_load(const char *fn)
735 {
736
737
738 if ((fn == 0) || (fn[0] == 0))
739 fn = SCRIPT_DEFAULT_FILENAME;
740
741 strcpy(conf.script_file, fn);
742
743 get_last_paramset_num();
744 script_scan();
745 load_params_values();
746
747 gui_update_script_submenu();
748 }
749
750
751
752 static const char* gui_script_param_set_enum(int change, __attribute__ ((unused))int arg)
753 {
754 static const char* modes[]={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Default" };
755
756 if (change != 0)
757 {
758 save_params_values(0);
759 gui_enum_value_change(&conf.script_param_set,change,sizeof(modes)/sizeof(modes[0]));
760
761 if (conf.script_param_set == DEFAULT_PARAM_SET)
762 conf.script_param_save = 0;
763 else
764 conf.script_param_save = 1;
765
766 if ( !load_params_values() )
767 script_reset_to_default_params_values();
768 gui_update_script_submenu();
769 }
770
771 return modes[conf.script_param_set];
772 }
773
774 static void gui_load_script_selected(const char *fn)
775 {
776 if (fn)
777 {
778 gui_menu_cancel_redraw();
779 save_params_values(0);
780 script_load(fn);
781 gui_set_need_restore();
782 }
783 }
784
785 static void gui_load_script(__attribute__ ((unused))int arg)
786 {
787 libfselect->file_select(LANG_STR_SELECT_SCRIPT_FILE, conf.script_file, "A/CHDK/SCRIPTS", gui_load_script_selected);
788 }
789
790 #if 0
791 static void gui_reset_script_default(int arg)
792 {
793 gui_menu_cancel_redraw();
794 save_params_values(0);
795 conf.script_file[0] = 0;
796 script_load(conf.script_file);
797 gui_set_need_restore();
798 }
799 #endif
800
801 static void gui_load_script_default(__attribute__ ((unused))int arg)
802 {
803 script_reset_to_default_params_values();
804 gui_update_script_submenu();
805 save_params_values(1);
806 }
807
808 static const char* gui_script_autostart_modes[]= { "Off", "On", "Once", "ALT"};
809
810 static void cb_change_param_save_enum()
811 {
812 if (conf.script_param_set != DEFAULT_PARAM_SET)
813 {
814 if (conf.script_param_save)
815 save_params_values(0);
816 }
817 else
818 {
819 conf.script_param_save = 0;
820 }
821 }
822
823 static CMenuItem param_save[2] = {
824 MENU_ITEM (0, 0, MENUITEM_ENUM, gui_script_param_set_enum, 0 ),
825 MENU_ITEM (0, 0, MENUITEM_BOOL|MENUITEM_ARG_CALLBACK, &conf.script_param_save, (int)cb_change_param_save_enum ),
826 };
827
828
829 #define SCRIPT_SUBMENU_PARAMS_IDX 8
830 #define SCRIPT_SUBMENU_BOTTOM_IDX 34
831
832 static CMenuItem hdr_script_submenu_items[] = {
833 MENU_ITEM (0x35,LANG_MENU_SCRIPT_LOAD, MENUITEM_PROC, gui_load_script, 0 ),
834 MENU_ITEM (0x5f,LANG_MENU_SCRIPT_DELAY, MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.script_shoot_delay, 0 ),
835
836 MENU_ENUM2 (0x5f,LANG_MENU_SCRIPT_AUTOSTART, &conf.script_startup, gui_script_autostart_modes ),
837 MENU_ITEM (0x5c,LANG_MENU_LUA_RESTART, MENUITEM_BOOL, &conf.debug_lua_restart_on_error, 0 ),
838 MENU_ITEM (0x5d,LANG_MENU_SCRIPT_DEFAULT_VAL, MENUITEM_PROC, gui_load_script_default, 0 ),
839 MENU_ITEM (0x5e,LANG_MENU_SCRIPT_PARAM_SET, MENUITEM_STATE_VAL_PAIR, ¶m_save, 0 ),
840 MENU_ITEM (0x0 ,(int)script_title, MENUITEM_SEPARATOR, 0, 0 ),
841 };
842
843 static CMenuItem *script_submenu_items = 0;
844 int script_submenu_count = 0;
845
846 CMenu script_submenu = {0x27,LANG_MENU_SCRIPT_TITLE, 0 };
847
848 static void gui_update_script_submenu()
849 {
850 int i;
851 sc_param *p;
852
853 int warn = 0;
854 if (is_script_loaded && (!script_has_version || (cmp_chdk_version(chdk_version, script_version) < 0)))
855 {
856 warn = 1;
857 }
858
859
860 int f = (sizeof(hdr_script_submenu_items) / sizeof(CMenuItem)) + warn;
861 int n = f + script_param_count + 2;
862
863
864 if (script_submenu_items && (script_submenu_count < n))
865 {
866 free(script_submenu_items);
867 script_submenu_items = 0;
868 script_submenu_count = 0;
869 }
870
871
872 if (script_submenu_items == 0)
873 {
874 script_submenu_items = malloc(n * sizeof(CMenuItem));
875 memset(script_submenu_items, 0, n * sizeof(CMenuItem));
876
877 if (script_submenu_count < n)
878 script_submenu_count = n;
879 }
880
881
882 memcpy(script_submenu_items, hdr_script_submenu_items, sizeof(hdr_script_submenu_items));
883
884
885 if (warn)
886 {
887 if (cmp_chdk_version(chdk_version, script_version) < 0)
888 {
889 static char warning[50];
890 sprintf(warning, "Script requires CHDK ver: %d.%d.%d.%d", script_version.major, script_version.minor, script_version.maintenance, script_version.revision);
891 script_submenu_items[f-1].text = (int)warning;
892 script_submenu_items[f-1].type = MENUITEM_ERROR;
893 }
894 else
895 {
896 script_submenu_items[f-1].text = (int)"No @chdk_version, assuming CHDK 1.3";
897 script_submenu_items[f-1].type = MENUITEM_WARNING;
898 }
899 }
900
901
902 script_submenu.menu = script_submenu_items;
903
904
905 for (i=f, p=script_params; p; i++, p=p->next)
906 {
907 script_submenu_items[i].symbol = 0x0;
908 script_submenu_items[i].text = (int)p->desc;
909 script_submenu_items[i].type = p->range_type;
910 script_submenu_items[i].value = &p->val;
911 script_submenu_items[i].arg = p->range;
912
913 if (p->option_count != 0)
914 {
915 script_submenu_items[i].opt_len = p->option_count;
916 script_submenu_items[i].arg = (int)p->options;
917 }
918 }
919
920
921 memset(&script_submenu_items[i],0,sizeof(CMenuItem)*2);
922 script_submenu_items[i].symbol = 0x51;
923 script_submenu_items[i].text = LANG_MENU_BACK;
924 script_submenu_items[i].type = MENUITEM_UP;
925 }
926
927