19 #include "img_format.h"
23 #include "menu_list.h"
24 #include "input/input.h"
25 #include "osdep/keycodes.h"
34 char* dir
; // current dir
43 static struct menu_priv_s cfg_dflt
= {
54 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
56 static m_option_t cfg_fields
[] = {
57 MENU_LIST_PRIV_FIELDS
,
58 { "path", ST_OFF(path
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
59 { "title", ST_OFF(title
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
60 { "file-action", ST_OFF(file_action
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
61 { "dir-action", ST_OFF(dir_action
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
62 { "auto-close", ST_OFF(auto_close
), CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
63 { NULL
, NULL
, NULL
, 0,0,0,NULL
}
66 #define mpriv (menu->priv)
68 static void free_entry(list_entry_t
* entry
) {
73 static char* replace_path(char* title
, char* dir
) {
74 char *p
= strstr(title
,"%p");
76 int tl
= strlen(title
);
80 char *r
, *n
, *d
= dir
;
84 if (*d
== '\\' || *d
== term
)
91 if (*dir
== '\\' || *dir
== term
)
93 } while ((*n
++ = *dir
++));
101 typedef int (*kill_warn
)(const void*, const void*);
103 static int mylstat(char *dir
, char *file
,struct stat
* st
) {
104 int l
= strlen(dir
) + strlen(file
);
106 sprintf(s
,"%s/%s",dir
,file
);
110 static int compare(char **a
, char **b
){
111 if((*a
)[strlen(*a
) - 1] == '/') {
112 if((*b
)[strlen(*b
) - 1] == '/')
113 return strcmp(*b
, *a
) ;
117 if((*b
)[strlen(*b
) - 1] == '/')
120 return strcmp(*b
, *a
);
124 static int open_dir(menu_t
* menu
,char* args
) {
125 char **namelist
, **tp
;
133 menu_list_init(menu
);
137 mpriv
->dir
= strdup(args
);
138 if(mpriv
->p
.title
&& mpriv
->p
.title
!= mpriv
->title
&& mpriv
->p
.title
!= cfg_dflt
.p
.title
)
139 free(mpriv
->p
.title
);
140 p
= strstr(mpriv
->title
,"%p");
142 mpriv
->p
.title
= replace_path(mpriv
->title
,mpriv
->dir
);
144 if ((dirp
= opendir (mpriv
->dir
)) == NULL
){
145 printf("opendir error: %s", strerror(errno
));
149 namelist
= (char **) malloc(sizeof(char *));
152 while ((dp
= readdir(dirp
)) != NULL
) {
153 if(dp
->d_name
[0] == '.' && strcmp(dp
->d_name
,"..") != 0)
155 if(n
%20 == 0){ // Get some more mem
156 if((tp
= (char **) realloc(namelist
, (n
+20) * sizeof (char *)))
158 printf("realloc error: %s", strerror(errno
));
165 namelist
[n
] = (char *) malloc(strlen(dp
->d_name
) + 2);
166 if(namelist
[n
] == NULL
){
167 printf("malloc error: %s", strerror(errno
));
172 strcpy(namelist
[n
], dp
->d_name
);
173 mylstat(args
,namelist
[n
],&st
);
174 if(S_ISDIR(st
.st_mode
))
175 strcat(namelist
[n
], "/");
182 qsort(namelist
, n
, sizeof(char *), (kill_warn
)compare
);
185 printf("readdir error: %s\n",strerror(errno
));
189 if((e
= calloc(1,sizeof(list_entry_t
))) != NULL
){
191 e
->p
.txt
= strdup(namelist
[n
]);
192 if(strchr(namelist
[n
], '/') != NULL
)
194 menu_list_add_entry(menu
,e
);
196 printf("malloc error: %s", strerror(errno
));
206 static void read_cmd(menu_t
* menu
,int cmd
) {
211 if(mpriv
->p
.current
->d
) {
212 if(mpriv
->dir_action
) {
213 int fname_len
= strlen(mpriv
->dir
) + strlen(mpriv
->p
.current
->p
.txt
) + 1;
214 char filename
[fname_len
];
216 sprintf(filename
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
217 str
= replace_path(mpriv
->dir_action
,filename
);
218 c
= mp_input_parse_cmd(str
);
219 if(str
!= mpriv
->dir_action
)
221 } else { // Default action : open this dirctory ourself
222 int l
= strlen(mpriv
->dir
);
223 char *slash
= NULL
, *p
= NULL
;
224 if(strcmp(mpriv
->p
.current
->p
.txt
,"../") == 0) {
226 mpriv
->dir
[l
-1] = '\0';
227 slash
= strrchr(mpriv
->dir
,'/');
230 p
= strdup(mpriv
->dir
);
232 p
= malloc(l
+ strlen(mpriv
->p
.current
->p
.txt
) + 1);
233 sprintf(p
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
235 menu_list_uninit(menu
,free_entry
);
236 if(!open_dir(menu
,p
)) {
237 printf("Can't open directory %s\n",p
);
243 int fname_len
= strlen(mpriv
->dir
) + strlen(mpriv
->p
.current
->p
.txt
) + 1;
244 char filename
[fname_len
];
246 sprintf(filename
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
247 str
= replace_path(mpriv
->file_action
,filename
);
248 c
= mp_input_parse_cmd(str
);
249 if(str
!= mpriv
->file_action
)
253 mp_input_queue_cmd(c
);
254 if(mpriv
->auto_close
)
259 menu_list_read_cmd(menu
,cmd
);
263 static void read_key(menu_t
* menu
,int c
){
265 mpriv
->p
.current
= mpriv
->p
.menu
; // Hack : we consider that the first entry is ../
266 read_cmd(menu
,MENU_CMD_OK
);
268 menu_list_read_key(menu
,c
,1);
271 static void clos(menu_t
* menu
) {
272 menu_list_uninit(menu
,free_entry
);
276 static int open_fs(menu_t
* menu
, char* args
) {
277 char *path
= mpriv
->path
;
280 args
= NULL
; // Warning kill
282 menu
->draw
= menu_list_draw
;
283 menu
->read_cmd
= read_cmd
;
284 menu
->read_key
= read_key
;
288 if(!path
|| path
[0] == '\0') {
289 int l
= strlen(wd
) + 2;
292 r
= open_dir(menu
,b
);
293 } else if(path
[0] != '/') {
294 int al
= strlen(path
);
295 int l
= strlen(wd
) + al
+ 3;
298 sprintf(b
,"%s/%s/",wd
,path
);
300 sprintf(b
,"%s/%s",wd
,path
);
301 r
= open_dir(menu
,b
);
303 r
= open_dir(menu
,path
);
308 const menu_info_t menu_info_filesel
= {
315 sizeof(struct menu_priv_s
),