Root/alfilesel/files/alfilesel.c

1/* Simple liballegro based file selector helper utility.
2 *
3 * Copyright (C) 2012 David Kühling <dvdkhlng TA gmx TOD de>
4 *
5 * License: GPL3 or later, NO WARRANTY
6 *
7 * Created: Apr 2012
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <getopt.h>
13
14#include <allegro.h>
15#include <loadpng.h>
16#include <jpgalleg.h>
17
18
19static int verbose_flag = 0;
20static int mouse_flag = 0;
21static int help_flag = 0;
22
23char * program_invocation_short_name;
24
25static void print_help() {
26   const char *help =
27      "[OPTION] [--] [PROGRAM_TO_RUN] [PROGRAM_ARGS]..\n"
28      "\n"
29      "If PROGRAM_TO_RUN is specfied, run it with arguments PROGRAM_ARGS and\n"
30      "the selected file appended as final argument.\n"
31      "Else just print the selected filename and newline to stdout.\n"
32      "\n"
33      "Options:\n"
34      "\t-t --title=STRING\n"
35      "\t\tSet file selector dialog's title\n"
36      "\t-w --wallpaper=FILENAME\n"
37      "\t\tSet file to use as wallpaper (supports jpeg, png, pcx, bmp, tga)\n"
38      "\t-p --path=PATH\n"
39      "\t\tSet initial directory and/or filename. When giving an initial\n"
40      "\t\tdirectory, make sure that PATH ends in a slash.\n"
41      "\t-f --filter=STRING\n"
42      "\t\tFilter files by extension and/or mode bits\n"
43      "\t\tUse 'png;jpeg' to show only .png and .jpeg files, use '/+x' to\n"
44      "\t\tonly show executable files etc.\n"
45      "\t-m --mouse\n"
46      "\t\tenable mouse (disabled by default)\n";
47   
48   printf ("USAGE: %s %s", program_invocation_short_name,
49       help);
50}
51
52int main (int argc, char *argv[])
53{
54   int c;
55   const int hborder = 32;
56   const int vborder = 32;
57   const int trborder = 6;
58   const char *title = "Select file";
59   const char *init_path = 0;
60   const char *filter = 0;
61   const char *wallpaper =
62      "/usr/share/gmenu2x/skins/Default/wallpapers/default.png";
63   char path[4096];
64   char **cmd = NULL;
65   int num_cmd = 0;
66   int run = 0;
67
68   PALETTE pal;
69   BITMAP *backbmp;
70
71   while (1)
72   {
73      static struct option long_options[] =
74     {
75        /* These options set a flag. */
76        {"verbose", no_argument, &verbose_flag, 1},
77        {"help", no_argument, &help_flag, 1},
78        {"mouse", no_argument, &mouse_flag, 1},
79        /* These options don't set a flag.
80           We distinguish them by their indices. */
81        {"title", required_argument, 0, 't'},
82        {"path", required_argument, 0, 'p'},
83        {"filter", required_argument, 0, 'f'},
84        {"wallpaper", required_argument, 0, 'w'},
85        {0, 0, 0, 0}
86     };
87      /* `getopt_long' stores the option index here. */
88      int option_index = 0;
89
90      c = getopt_long (argc, argv, "t:p:f:w:mh",
91               long_options, &option_index);
92
93      /* Detect the end of the options. */
94      if (c == -1)
95     break;
96
97      switch (c)
98      {
99     case 0:
100        /* If this option set a flag, do nothing else now. */
101        if (long_options[option_index].flag != 0)
102           break;
103        break;
104
105     case 'h':
106        help_flag = 1;
107        break;
108
109     case 'm':
110        mouse_flag = 1;
111        break;
112
113     case 't':
114        title = optarg;
115        break;
116
117     case 'p':
118        init_path = optarg;
119        break;
120
121     case 'f':
122        filter = optarg;
123        break;
124
125     case 'w':
126        wallpaper = optarg;
127        break;
128
129     case '?':
130        /* `getopt_long' already printed an error message. */
131        print_help();
132        return 1;
133
134     default:
135        abort ();
136      }
137   }
138
139   if (help_flag)
140   {
141      print_help();
142      return 0;
143   }
144
145   /* Print any remaining command line arguments (not options). */
146   if (optind < argc)
147   {
148      run = 1;
149      cmd = &argv[optind];
150      num_cmd = argc - optind;
151      printf ("non-option ARGV-elements: ");
152      while (optind < argc)
153     printf ("%s ", argv[optind++]);
154      putchar ('\n');
155   }
156
157   if (allegro_init() != 0)
158      return 1;
159   install_keyboard();
160   if (mouse_flag)
161      install_mouse();
162   install_timer();
163   loadpng_init();
164   jpgalleg_init();
165
166   set_color_depth(32);
167   if (set_gfx_mode(GFX_SAFE, 320, 240, 0, 0) != 0) {
168      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
169      allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
170      return 1;
171   }
172
173   backbmp = load_bitmap(wallpaper, pal);
174   if (backbmp)
175   {
176      if (bitmap_color_depth(backbmp) == 8)
177     set_palette(pal);
178
179      /* can't stretch_blit() between color depths, so doing the stretching on
180     a memory bitmap of matching depth, then blit to the screen */
181      BITMAP *buffer = create_bitmap_ex(bitmap_color_depth(backbmp),
182                    SCREEN_W, SCREEN_H);
183
184      if (!buffer)
185      {
186     set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
187     allegro_message("Unable to allocate bitmap\n%s\n", allegro_error);
188     return 1;
189      }
190
191      stretch_blit(backbmp, buffer, 0, 0, backbmp->w, backbmp->h,
192           0, 0, SCREEN_W, SCREEN_H);
193      blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
194      destroy_bitmap(buffer);
195   }
196   else
197   {
198      /* couln't load file (maybe default filename not present...?) */
199      clear_to_color(screen, makecol(0,0,0));
200   }
201   
202   set_palette(pal);
203
204   /* fourth parameter is alpha value (0=fully transparent) */
205   gui_fg_color = makecol(230,210,140);
206   gui_mg_color = makecol(140,150,160);
207   gui_bg_color = makecol(30,40,50);
208
209   /* add some translucent border around file selector dialog. We'd like to
210      make the whole dialog translucent by using makeacol() above and
211      set_alpha_blender(), however the dialog can't cope with some of the
212      changes in drawing function semantics that go along with that */
213   drawing_mode(DRAW_MODE_TRANS, 0, 0, 0);
214   set_trans_blender(0,0,0,128);
215   rectfill(screen, hborder-trborder, vborder-trborder,
216        SCREEN_W-hborder+trborder, SCREEN_H-vborder+trborder,
217        gui_bg_color);
218   drawing_mode(DRAW_MODE_SOLID, 0, 0, 0);
219
220   if (!init_path)
221      getcwd(path, sizeof(path));
222   else
223      strncpy(path, init_path, sizeof(path));
224
225   path[sizeof(path)-1] = '\0';
226
227   int ok = file_select_ex(
228      title, path, filter, sizeof(path), SCREEN_W-2*hborder, SCREEN_H-2*vborder);
229   path[sizeof(path)-1] = '\0';
230
231   allegro_exit();
232
233   if (ok)
234   {
235      printf ("%s\n", path);
236
237      if (run)
238      {
239     char **argv_exec = malloc(sizeof(char*)*(num_cmd+2));
240     if (!argv_exec)
241        return 2;
242     memcpy (argv_exec, cmd, sizeof(char*)*(num_cmd));
243     argv_exec[num_cmd] = path;
244     argv_exec[num_cmd+1] = 0;
245     
246     if (execvp(cmd[0], argv_exec))
247     {
248        perror ("Can't exec");
249        return 3;
250     }
251
252     /* exec shouldn't return! */
253     return 4;
254      }
255      
256      return 0;
257   }
258
259   return 1;
260}
261
262
263/* The following comments configure the Emacs editor. Just ignore them.
264 * Local Variables:
265 * compile-command: "make -C ~/h/src/qi/openwrt-xburst package/alfilesel/compile -j2 V=99"
266 * End:
267 */
268

Archive Download this file



interactive