14 #include "../config.h"
16 #include "../m_struct.h"
17 #include "../m_option.h"
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
], "/");
180 qsort(namelist
, n
, sizeof(char *), (kill_warn
)compare
);
183 printf("readdir error: %s\n",strerror(errno
));
187 if((e
= calloc(1,sizeof(list_entry_t
))) != NULL
){
189 e
->p
.txt
= strdup(namelist
[n
]);
190 if(strchr(namelist
[n
], '/') != NULL
)
192 menu_list_add_entry(menu
,e
);
194 printf("malloc error: %s", strerror(errno
));
204 static void read_cmd(menu_t
* menu
,int cmd
) {
209 if(mpriv
->p
.current
->d
) {
210 if(mpriv
->dir_action
) {
211 int fname_len
= strlen(mpriv
->dir
) + strlen(mpriv
->p
.current
->p
.txt
) + 1;
212 char filename
[fname_len
];
214 sprintf(filename
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
215 str
= replace_path(mpriv
->dir_action
,filename
);
216 c
= mp_input_parse_cmd(str
);
217 if(str
!= mpriv
->dir_action
)
219 } else { // Default action : open this dirctory ourself
220 int l
= strlen(mpriv
->dir
);
221 char *slash
= NULL
, *p
= NULL
;
222 if(strcmp(mpriv
->p
.current
->p
.txt
,"../") == 0) {
224 mpriv
->dir
[l
-1] = '\0';
225 slash
= strrchr(mpriv
->dir
,'/');
228 p
= strdup(mpriv
->dir
);
230 p
= malloc(l
+ strlen(mpriv
->p
.current
->p
.txt
) + 1);
231 sprintf(p
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
233 menu_list_uninit(menu
,free_entry
);
234 if(!open_dir(menu
,p
)) {
235 printf("Can't open directory %s\n",p
);
241 int fname_len
= strlen(mpriv
->dir
) + strlen(mpriv
->p
.current
->p
.txt
) + 1;
242 char filename
[fname_len
];
244 sprintf(filename
,"%s%s",mpriv
->dir
,mpriv
->p
.current
->p
.txt
);
245 str
= replace_path(mpriv
->file_action
,filename
);
246 c
= mp_input_parse_cmd(str
);
247 if(str
!= mpriv
->file_action
)
251 mp_input_queue_cmd(c
);
252 if(mpriv
->auto_close
)
257 menu_list_read_cmd(menu
,cmd
);
261 static void read_key(menu_t
* menu
,int c
){
263 mpriv
->p
.current
= mpriv
->p
.menu
; // Hack : we consider that the first entry is ../
264 read_cmd(menu
,MENU_CMD_OK
);
266 menu_list_read_key(menu
,c
,1);
269 static void clos(menu_t
* menu
) {
270 menu_list_uninit(menu
,free_entry
);
274 static int open_fs(menu_t
* menu
, char* args
) {
275 char *path
= mpriv
->path
;
278 args
= NULL
; // Warning kill
280 menu
->draw
= menu_list_draw
;
281 menu
->read_cmd
= read_cmd
;
282 menu
->read_key
= read_key
;
286 if(!path
|| path
[0] == '\0') {
287 int l
= strlen(wd
) + 2;
290 r
= open_dir(menu
,b
);
291 } else if(path
[0] != '/') {
292 int al
= strlen(path
);
293 int l
= strlen(wd
) + al
+ 3;
296 sprintf(b
,"%s/%s/",wd
,path
);
298 sprintf(b
,"%s/%s",wd
,path
);
299 r
= open_dir(menu
,b
);
301 r
= open_dir(menu
,path
);
306 const menu_info_t menu_info_filesel
= {
313 sizeof(struct menu_priv_s
),