~ubuntu-branches/ubuntu/precise/vice/precise

« back to all changes in this revision

Viewing changes to src/arch/msdos/tuifs.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2010-02-11 18:30:16 UTC
  • mfrom: (1.1.8 upstream) (9.2.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100211183016-f6n8usn3tzp0u6dp
Tags: 2.2.dfsg-1
* New upstream release, C64 DTV is included so update package description
  and add it to the menu.
* Drop patch fixing build failure with gcc-4.4 , applied upstream.
* Fix some lintian problems and clean up debian/rules .

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
{
75
75
    struct file_list *new_list;
76
76
 
77
 
    new_list = (struct file_list *)lib_malloc(sizeof(struct file_list));
 
77
    new_list = lib_malloc(sizeof(struct file_list));
78
78
    new_list->num_items = new_list->num_used_items = 0;
79
79
    new_list->items = NULL;
80
80
 
83
83
 
84
84
static void file_list_clear(struct file_list *fl)
85
85
{
86
 
    if (fl->items != NULL)
87
 
        lib_free(fl->items);
88
 
 
 
86
    lib_free(fl->items);
89
87
    fl->items = NULL;
90
88
    fl->num_used_items = fl->num_items = 0;
91
89
}
98
96
    }
99
97
}
100
98
 
101
 
static void file_list_add_item(struct file_list *fl, const char *name,
102
 
                               enum file_type type)
 
99
static void file_list_add_item(struct file_list *fl, const char *name, enum file_type type)
103
100
{
104
101
    if (fl->num_items == fl->num_used_items) {
105
102
        fl->num_items += 100;
106
 
        if (fl->items != NULL)
107
 
            fl->items = (struct file_item *)lib_realloc(fl->items,
108
 
                                                        fl->num_items
109
 
                                                        * sizeof(*fl->items));
110
 
        else
111
 
            fl->items = (struct file_item *)lib_malloc(fl->num_items
112
 
                                                       * sizeof(*fl->items));
 
103
        if (fl->items != NULL) {
 
104
            fl->items = lib_realloc(fl->items, fl->num_items * sizeof(*fl->items));
 
105
        } else {
 
106
            fl->items = lib_malloc(fl->num_items * sizeof(*fl->items));
 
107
        }
113
108
    }
114
109
 
115
110
    strcpy(fl->items[fl->num_used_items].name, name);
124
119
 
125
120
    /* Directories always come first. */
126
121
    if (f1->type != f2->type) {
127
 
        if (f1->type == FT_DIR)
 
122
        if (f1->type == FT_DIR) {
128
123
            return -1;
129
 
        if (f2->type == FT_DIR)
 
124
        }
 
125
        if (f2->type == FT_DIR) {
130
126
            return +1;
 
127
        }
131
128
    }
132
129
    return strcasecmp(f1->name, f2->name);
133
130
}
134
131
 
135
132
static void file_list_sort(struct file_list *fl)
136
133
{
137
 
    qsort(fl->items, fl->num_used_items, sizeof(struct file_item),
138
 
          file_list_sort_func);
 
134
    qsort(fl->items, fl->num_used_items, sizeof(struct file_item), file_list_sort_func);
139
135
}
140
136
 
141
137
/* XXX: Assumes `path' ends with a slash.  */
142
 
static struct file_list *file_list_read_lfn(const char *path,
143
 
                                            const char *pattern)
 
138
static struct file_list *file_list_read_lfn(const char *path, const char *pattern)
144
139
{
145
140
    struct dirent *d;
146
141
    struct file_list *fl;
147
142
    DIR *ds;
148
143
    int pathlen = strlen(path);
149
144
 
150
 
    if (path == NULL || *path == '\0')
 
145
    if (path == NULL || *path == '\0') {
151
146
        ds = opendir(".");
152
 
    else
 
147
    } else {
153
148
        ds = opendir(path);
 
149
    }
154
150
 
155
 
    if (ds == NULL)
 
151
    if (ds == NULL) {
156
152
        return NULL;
 
153
    }
157
154
 
158
155
    fl = file_list_create();
159
156
 
165
162
 
166
163
        /* This makes `stat()' faster.  FIXME: but it's still too slow
167
164
           imo...  */
168
 
        _djstat_flags = (_STAT_INODE
169
 
                         | _STAT_EXEC_EXT
170
 
                         | _STAT_EXEC_MAGIC
171
 
                         | _STAT_DIRSIZE
172
 
                         | _STAT_ROOT_TIME
173
 
                         | _STAT_WRITEBIT);
 
165
        _djstat_flags = (_STAT_INODE | _STAT_EXEC_EXT | _STAT_EXEC_MAGIC | _STAT_DIRSIZE | _STAT_ROOT_TIME | _STAT_WRITEBIT);
174
166
 
175
 
        while((d = readdir(ds)) != NULL) {
 
167
        while ((d = readdir(ds)) != NULL) {
176
168
            struct stat s;
177
169
            int type;
178
170
            /* Warning: Assumes `path' has a trailing '/'.  */
193
185
 
194
186
                    element = strtok(p, ";");
195
187
                    do {
196
 
                        if (fnmatch(element, d->d_name, FNM_NOCASE) == 0)
 
188
                        if (fnmatch(element, d->d_name, FNM_NOCASE) == 0) {
197
189
                            file_list_add_item(fl, d->d_name, type);
 
190
                        }
198
191
                        element = strtok(NULL, ";");
199
192
                    } while (element != NULL);
200
193
                    lib_free(p);
211
204
    return fl;
212
205
}
213
206
 
214
 
static struct file_list *file_list_read_nolfn(const char *path,
215
 
                                              const char *pattern)
 
207
static struct file_list *file_list_read_nolfn(const char *path, const char *pattern)
216
208
{
217
209
    char *cwd = ioutil_current_dir();
218
210
    struct file_list *fl = NULL;
219
211
    struct find_t f;
220
212
 
221
 
    if (cwd == NULL)
 
213
    if (cwd == NULL) {
222
214
        return NULL;
223
 
 
224
 
    if (ioutil_chdir(path) < 0)
225
 
        goto end;
226
 
 
227
 
    if (_dos_findfirst("*.*", (_A_NORMAL | _A_RDONLY | _A_HIDDEN
228
 
                               | _A_SYSTEM | _A_SUBDIR | _A_ARCH), &f))
229
 
        goto end;
 
215
    }
 
216
 
 
217
    if (ioutil_chdir(path) < 0) {
 
218
        goto end;
 
219
    }
 
220
 
 
221
    if (_dos_findfirst("*.*", (_A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR | _A_ARCH), &f)) {
 
222
        goto end;
 
223
    }
230
224
 
231
225
    fl = file_list_create();
232
226
 
235
229
    while (!_dos_findnext(&f)) {
236
230
        strlwr(f.name);
237
231
        if (pattern == NULL || (f.attrib & _A_SUBDIR)) {
238
 
            file_list_add_item(fl, f.name,
239
 
                               (f.attrib & _A_SUBDIR) ? FT_DIR : FT_NORMAL);
 
232
            file_list_add_item(fl, f.name, (f.attrib & _A_SUBDIR) ? FT_DIR : FT_NORMAL);
240
233
            continue;
241
234
        }
242
235
        {
245
238
 
246
239
            element = strtok(p, ";");
247
240
            do {
248
 
                if (fnmatch(element, f.name, FNM_NOCASE) == 0)
249
 
                    file_list_add_item(fl, f.name,
250
 
                                  (f.attrib & _A_SUBDIR) ? FT_DIR : FT_NORMAL);
 
241
                if (fnmatch(element, f.name, FNM_NOCASE) == 0) {
 
242
                    file_list_add_item(fl, f.name, (f.attrib & _A_SUBDIR) ? FT_DIR : FT_NORMAL);
 
243
                }
251
244
                element = strtok(NULL, ";");
252
245
            } while (element != NULL);
253
246
            lib_free(p);
261
254
    return fl;
262
255
}
263
256
 
264
 
static struct file_list *file_list_read(const char *path,
265
 
                                        const char *pattern)
 
257
static struct file_list *file_list_read(const char *path, const char *pattern)
266
258
{
267
259
    /* XXX: This check is only half-OK.  We actually need Allegro to be up
268
260
       and running for this to work properly.  */
271
263
#ifdef OSTYPE_WIN98
272
264
        || (os_type == OSTYPE_WIN98)
273
265
#endif
274
 
        || (os_type == OSTYPE_WINNT))
 
266
        || (os_type == OSTYPE_WINNT)) {
275
267
        return file_list_read_lfn(path, pattern);
276
 
    else
 
268
    } else {
277
269
        return file_list_read_nolfn(path, pattern);
 
270
    }
278
271
#else
279
272
    return file_list_read_lfn(path, pattern);
280
273
#endif
284
277
{
285
278
    int i;
286
279
 
287
 
    for (i = 0; i < fl->num_used_items; i++)
288
 
        if (strncasecmp(fl->items[i].name, str, len) == 0)
 
280
    for (i = 0; i < fl->num_used_items; i++) {
 
281
        if (strncasecmp(fl->items[i].name, str, len) == 0) {
289
282
            return i;
 
283
        }
 
284
    }
290
285
    return -1;
291
286
}
292
287
 
293
288
/* ------------------------------------------------------------------------- */
294
289
 
295
 
static void file_selector_display_path(const char *path,
296
 
                                       int x, int y, int width)
 
290
static void file_selector_display_path(const char *path, int x, int y, int width)
297
291
{
298
292
    int i, xx;
299
293
 
302
296
 
303
297
    tui_set_attr(MENU_FORE, MENU_BACK, 0);
304
298
 
305
 
    for (i = strlen(path) - 1, xx = MIN(x + width - 1, x + i);
306
 
         i >= 0 && xx >= x;
307
 
         i--, xx--) {
 
299
    for (i = strlen(path) - 1, xx = MIN(x + width - 1, x + i); i >= 0 && xx >= x; i--, xx--) {
308
300
        char c;
309
301
 
310
302
        /* Display ellipsis on the left if longer than the line.  */
311
 
        if (xx <= x + 1 && i > 1)
 
303
        if (xx <= x + 1 && i > 1) {
312
304
            c = '.';
313
 
        else
 
305
        } else {
314
306
            c = path[i] == '/' ? '\\' : path[i];
 
307
        }
315
308
        tui_put_char(xx, y, c);
316
309
    }
317
310
}
318
311
 
319
 
static void file_selector_display_item(struct file_list *fl, int num,
320
 
                                       int first_item_num, int x, int y,
321
 
                                       int width, int height, int num_cols)
 
312
static void file_selector_display_item(struct file_list *fl, int num, int first_item_num, int x, int y, int width, int height, int num_cols)
322
313
{
323
314
    y += (num - first_item_num) % height;
324
315
    x += ((num - first_item_num) / height) * width;
343
334
            name[width - 2] = '\0';
344
335
            tui_display(x, y, width, " %s ", name);
345
336
        } else {
346
 
            if (fl->items[num].type == FT_DIR)
347
 
              /* tui_display(x, y, width, " %s\\ ", fl->items[num].name); */
 
337
            if (fl->items[num].type == FT_DIR) {
348
338
                tui_display(x, y, width, " %s/ ", fl->items[num].name);
349
 
            else
 
339
            } else {
350
340
              tui_display(x, y, width, " %s ", fl->items[num].name);
 
341
            }
351
342
        }
352
343
    }
353
344
}
354
345
 
355
 
static void file_selector_update(struct file_list *fl,
356
 
                                 int first_item_num, int x, int y,
357
 
                                 int width, int height, int num_cols)
 
346
static void file_selector_update(struct file_list *fl, int first_item_num, int x, int y, int width, int height, int num_cols)
358
347
{
359
348
    int i;
360
349
 
361
 
    for (i = 0; i < num_cols * height; i++)
362
 
        file_selector_display_item(fl, first_item_num + i, first_item_num,
363
 
                                   x, y, width, height, num_cols);
 
350
    for (i = 0; i < num_cols * height; i++) {
 
351
        file_selector_display_item(fl, first_item_num + i, first_item_num, x, y, width, height, num_cols);
 
352
    }
364
353
}
365
354
 
366
355
/* ------------------------------------------------------------------------- */
384
373
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0
385
374
    };
386
375
 
387
 
    if (keycode < 0x100 || keycode >= 0x200)
 
376
    if (keycode < 0x100 || keycode >= 0x200) {
388
377
        return 0;
389
 
    else
 
378
    } else {
390
379
        return key_table[keycode - 0x100];
 
380
    }
391
381
}
392
382
 
393
383
/* Make sure there is a trailing '/' in `*path'.  */
402
392
    }
403
393
}
404
394
 
405
 
static char *change_path(struct file_list *fl, char *return_path,
406
 
                         int curr_item)
 
395
static char *change_path(struct file_list *fl, char *return_path, int curr_item)
407
396
{
408
397
    char *new_path;
409
398
 
410
399
    if (strcmp(fl->items[curr_item].name, "..") == 0) {
411
400
        char *p = return_path + strlen(return_path) - 1;
412
401
 
413
 
        if (*p == '/')
 
402
        if (*p == '/') {
414
403
            p--;
415
 
        for (; *p != '/' && p > return_path; p--)
416
 
                    ;
417
 
        if (p == return_path)
 
404
        }
 
405
        for (; *p != '/' && p > return_path; p--) {
 
406
        }
 
407
 
 
408
        if (p == return_path) {
418
409
            new_path = lib_stralloc(return_path);
419
 
        else {
 
410
        } else {
420
411
            new_path = lib_malloc(p - return_path + 2);
421
412
            memcpy(new_path, return_path, p - return_path + 1);
422
413
            new_path[p - return_path + 1] = '\0';
423
414
        }
424
415
    } else {
425
 
        new_path = util_concat(return_path,
426
 
                               fl->items[curr_item].name, "/", NULL);
 
416
        new_path = util_concat(return_path, fl->items[curr_item].name, "/", NULL);
427
417
    }
428
418
 
429
419
    return new_path;
432
422
/* FIXME: documentation.  */
433
423
char *tui_file_selector(const char *title, const char *directory,
434
424
                        const char *pattern, const char *default_item,
435
 
                        unsigned int type,
436
 
                        image_contents_t *(*contents_func)(unsigned int,
437
 
                        const char *, unsigned int),
438
 
                        unsigned int unit,
 
425
                        read_contents_func_type contents_func,
439
426
                        char **browse_file_return,
440
427
                        unsigned int *browse_file_number_return)
441
428
{
448
435
    int str_len = 0;
449
436
    tui_area_t backing_store = NULL;
450
437
 
451
 
    if (contents_func != NULL)
 
438
    if (contents_func != NULL) {
452
439
        *browse_file_return = NULL;
 
440
    }
453
441
 
454
 
    if (browse_file_number_return != NULL)
 
442
    if (browse_file_number_return != NULL) {
455
443
        *browse_file_number_return = 0;
 
444
    }
456
445
 
457
 
    if (directory != NULL)
 
446
    if (directory != NULL) {
458
447
        return_path = lib_stralloc(directory);
459
 
    else
 
448
    } else {
460
449
        return_path = ioutil_current_dir();
 
450
    }
461
451
 
462
452
    slashize_path(&return_path);
463
453
 
464
454
    fl = file_list_read(return_path, pattern);
465
 
    if (fl == NULL)
 
455
    if (fl == NULL) {
466
456
        return NULL;
 
457
    }
467
458
 
468
459
    first_item = curr_item = 0;
469
460
    num_cols = 4;
479
470
        for (i = 0; i < fl->num_items; i++) {
480
471
            if (!strcasecmp(default_item, fl->items[i].name)) {
481
472
                curr_item = i;
482
 
                while (curr_item - first_item >= num_files)
 
473
                while (curr_item - first_item >= num_files) {
483
474
                    first_item += num_lines;
 
475
                }
484
476
                break;
485
477
            }
486
478
        }
493
485
 
494
486
    tui_area_get(&backing_store, x, y, width + 2, height + 1);
495
487
 
496
 
    tui_display_window(x, y, width, height, MENU_BORDER, MENU_BACK,
497
 
                       title, NULL);
 
488
    tui_display_window(x, y, width, height, MENU_BORDER, MENU_BACK, title, NULL);
498
489
 
499
490
    while (1) {
500
491
        int key;
501
492
 
502
493
        tui_set_attr(MENU_FORE, MENU_BACK, 0);
503
494
        if (need_update) {
504
 
            file_selector_display_path(return_path, x + 1, y + height - 1,
505
 
                                       width - 2);
506
 
            file_selector_update(fl, first_item, x + 2, y + 1,
507
 
                                 field_width, num_lines, num_cols);
 
495
            file_selector_display_path(return_path, x + 1, y + height - 1, width - 2);
 
496
            file_selector_update(fl, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
508
497
            tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0);
509
 
            tui_display(0, tui_num_lines() - 1, tui_num_cols(),
510
 
                        "\030\031\033\032: Move  <Enter>: Select  %s<Alt>-<letter>: Change drive",
511
 
                        contents_func != NULL ? "<Space>: Preview  " : "");
 
498
            tui_display(0, tui_num_lines() - 1, tui_num_cols(), "\030\031\033\032: Move  <Enter>: Select  %s<Alt>-<letter>: Change drive", contents_func != NULL ? "<Space>: Preview  " : "");
512
499
            need_update = 0;
513
500
        }
514
501
        tui_set_attr(MENU_FORE, MENU_HIGHLIGHT, 0);
515
 
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1,
516
 
                                   field_width, num_lines, num_cols);
 
502
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
517
503
        key = getkey();
518
504
        tui_set_attr(MENU_FORE, MENU_BACK, 0);
519
 
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1,
520
 
                                   field_width, num_lines, num_cols);
 
505
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
521
506
 
522
507
        switch (key) {
523
 
          case K_Escape:
524
 
            tui_area_put(backing_store, x, y);
525
 
            tui_area_free(backing_store);
526
 
            return NULL;
527
 
          case K_Left:
528
 
            str_len = 0;
529
 
            if (curr_item - num_lines >= 0) {
530
 
                curr_item -= num_lines;
531
 
                if (curr_item < first_item) {
532
 
                    if (first_item >= num_lines) {
533
 
                        first_item -= num_lines;
534
 
                        need_update = 1;
535
 
                    } else
536
 
                        curr_item += num_lines;
537
 
                }
538
 
            }
539
 
            break;
540
 
          case K_Up:
541
 
            str_len = 0;
542
 
            if (curr_item > 0) {
543
 
                curr_item--;
544
 
                if (curr_item < first_item) {
545
 
                    first_item = curr_item;
546
 
                    need_update = 1;
547
 
                }
548
 
            }
549
 
            break;
550
 
          case K_Right:
551
 
            str_len = 0;
552
 
            if (curr_item + num_lines < fl->num_used_items) {
553
 
                curr_item += num_lines;
554
 
                if (curr_item - first_item >= num_files) {
555
 
                    first_item += num_lines;
556
 
                    need_update = 1;
557
 
                }
558
 
            }
559
 
            break;
560
 
          case K_Down:
561
 
            str_len = 0;
562
 
            if (curr_item < fl->num_used_items - 1) {
563
 
                curr_item++;
564
 
                if (curr_item == first_item + num_files) {
565
 
                    first_item++;
566
 
                    need_update = 1;
567
 
                }
568
 
            }
569
 
            break;
570
 
          case K_PageDown:
571
 
            str_len = 0;
572
 
            if (curr_item + num_files < fl->num_used_items) {
573
 
                curr_item += num_files;
574
 
                first_item += num_files;
575
 
            }
576
 
            need_update = 1;
577
 
            break;
578
 
          case K_PageUp:
579
 
            str_len = 0;
580
 
            if (curr_item - num_files >= 0) {
581
 
                curr_item -= num_files;
582
 
                first_item -= num_files;
583
 
                if (first_item < 0)
584
 
                    first_item = 0;
585
 
                need_update = 1;
586
 
            }
587
 
            break;
588
 
          case K_Home:
589
 
            str_len = 0;
590
 
            curr_item = 0;
591
 
            if (first_item != 0) {
592
 
                first_item = 0;
593
 
                need_update = 1;
594
 
            }
595
 
            break;
596
 
          case K_End:
597
 
            str_len = 0;
598
 
            curr_item = fl->num_used_items - 1;
599
 
            first_item = curr_item - num_files + 1;
600
 
            if (first_item < 0)
601
 
                first_item = 0;
602
 
            need_update = 1;
603
 
            break;
604
 
          case K_Return:
605
 
            str_len = 0;
606
 
            if (fl->items[curr_item].type == FT_DIR) {
607
 
                struct file_list *new_fl;
608
 
                char *new_path;
609
 
 
610
 
                new_path = change_path(fl, return_path, curr_item);
611
 
 
612
 
                new_fl = file_list_read(new_path, pattern);
613
 
 
614
 
                if (new_fl != NULL) {
615
 
                    file_list_free(fl);
616
 
                    fl = new_fl;
617
 
                    first_item = curr_item = 0;
618
 
                    lib_free(return_path);
619
 
                    return_path = new_path;
620
 
                    need_update = 1;
621
 
                    ioutil_chdir(return_path);
622
 
                } else {
623
 
                    lib_free(new_path);
624
 
                }
625
 
            } else {
626
 
                char *p = util_concat(return_path, fl->items[curr_item].name,
627
 
                                      NULL);
628
 
 
629
 
                lib_free(return_path);
630
 
                return_path = p;
 
508
            case K_Escape:
631
509
                tui_area_put(backing_store, x, y);
632
510
                tui_area_free(backing_store);
633
 
                return return_path;
634
 
            }
635
 
            break;
636
 
          case K_BackSpace:
637
 
            if (str_len > 1) {
638
 
                int n;
639
 
                str_len--;
640
 
                n = file_list_find(fl, str, str_len);
641
 
                if (n >= 0) {
642
 
                    curr_item = n;
 
511
                return NULL;
 
512
            case K_Left:
 
513
                str_len = 0;
 
514
                if (curr_item - num_lines >= 0) {
 
515
                    curr_item -= num_lines;
 
516
                    if (curr_item < first_item) {
 
517
                        if (first_item >= num_lines) {
 
518
                            first_item -= num_lines;
 
519
                            need_update = 1;
 
520
                        } else {
 
521
                            curr_item += num_lines;
 
522
                        }
 
523
                    }
 
524
                }
 
525
                break;
 
526
            case K_Up:
 
527
                str_len = 0;
 
528
                if (curr_item > 0) {
 
529
                    curr_item--;
643
530
                    if (curr_item < first_item) {
644
531
                        first_item = curr_item;
645
532
                        need_update = 1;
646
 
                    } else if (first_item + num_files <= curr_item) {
647
 
                        first_item = curr_item - num_files + 1;
648
 
                        need_update = 1;
649
 
                    }
650
 
                }
651
 
            } else {
 
533
                    }
 
534
                }
 
535
                break;
 
536
            case K_Right:
 
537
                str_len = 0;
 
538
                if (curr_item + num_lines < fl->num_used_items) {
 
539
                    curr_item += num_lines;
 
540
                    if (curr_item - first_item >= num_files) {
 
541
                        first_item += num_lines;
 
542
                        need_update = 1;
 
543
                    }
 
544
                }
 
545
                break;
 
546
            case K_Down:
 
547
                str_len = 0;
 
548
                if (curr_item < fl->num_used_items - 1) {
 
549
                    curr_item++;
 
550
                    if (curr_item == first_item + num_files) {
 
551
                        first_item++;
 
552
                        need_update = 1;
 
553
                    }
 
554
                }
 
555
                break;
 
556
            case K_PageDown:
 
557
                str_len = 0;
 
558
                if (curr_item + num_files < fl->num_used_items) {
 
559
                    curr_item += num_files;
 
560
                    first_item += num_files;
 
561
                }
 
562
                need_update = 1;
 
563
                break;
 
564
            case K_PageUp:
 
565
                str_len = 0;
 
566
                if (curr_item - num_files >= 0) {
 
567
                    curr_item -= num_files;
 
568
                    first_item -= num_files;
 
569
                    if (first_item < 0) {
 
570
                        first_item = 0;
 
571
                    }
 
572
                    need_update = 1;
 
573
                }
 
574
                break;
 
575
            case K_Home:
652
576
                str_len = 0;
653
577
                curr_item = 0;
654
578
                if (first_item != 0) {
655
579
                    first_item = 0;
656
580
                    need_update = 1;
657
581
                }
658
 
            }
659
 
            break;
660
 
          case ' ':
661
 
            if (contents_func != NULL
662
 
                && fl->items[curr_item].type != FT_DIR
663
 
                && browse_file_return != NULL) {
664
 
                tui_display(0, tui_num_lines() - 1, tui_num_cols(), "");
665
 
                *browse_file_return = tui_image_browser(type,
666
 
                                          fl->items[curr_item].name,
667
 
                                          contents_func, unit,
668
 
                                          browse_file_number_return);
669
 
                if (*browse_file_return != NULL) {
670
 
                    char *p = util_concat(return_path,
671
 
                                          fl->items[curr_item].name, NULL);
 
582
                break;
 
583
            case K_End:
 
584
                str_len = 0;
 
585
                curr_item = fl->num_used_items - 1;
 
586
                first_item = curr_item - num_files + 1;
 
587
                if (first_item < 0) {
 
588
                    first_item = 0;
 
589
                }
 
590
                need_update = 1;
 
591
                break;
 
592
            case K_Return:
 
593
                str_len = 0;
 
594
                if (fl->items[curr_item].type == FT_DIR) {
 
595
                    struct file_list *new_fl;
 
596
                    char *new_path;
 
597
 
 
598
                    new_path = change_path(fl, return_path, curr_item);
 
599
 
 
600
                    new_fl = file_list_read(new_path, pattern);
 
601
 
 
602
                    if (new_fl != NULL) {
 
603
                        file_list_free(fl);
 
604
                        fl = new_fl;
 
605
                        first_item = curr_item = 0;
 
606
                        lib_free(return_path);
 
607
                        return_path = new_path;
 
608
                        need_update = 1;
 
609
                        ioutil_chdir(return_path);
 
610
                    } else {
 
611
                        lib_free(new_path);
 
612
                    }
 
613
                } else {
 
614
                    char *p = util_concat(return_path, fl->items[curr_item].name, NULL);
672
615
 
673
616
                    lib_free(return_path);
674
617
                    return_path = p;
676
619
                    tui_area_free(backing_store);
677
620
                    return return_path;
678
621
                }
679
 
                need_update = 1;
680
622
                break;
681
 
            } else {
682
 
                tui_beep();
683
 
            }
684
 
          default:
685
 
            {
686
 
                int drive_num;
687
 
 
688
 
                drive_num = alt_key_to_drive_num(key);
689
 
 
690
 
                if (drive_num > 0) {
691
 
                    /* `A-a' ... `A-z' change the current drive.  */
692
 
                    int num_available_drives;
693
 
                    int current_drive;
694
 
 
695
 
                    _dos_getdrive(&current_drive);
696
 
                    _dos_setdrive(current_drive, &num_available_drives);
697
 
                    if (drive_num <= num_available_drives) {
698
 
                        char *new_path;
699
 
 
700
 
                        /* FIXME: This is a hack...  Maybe there is a cleaner
701
 
                           way to do it, but for now I just don't know.  */
702
 
                        _dos_setdrive(drive_num, &num_available_drives);
703
 
                        new_path = ioutil_current_dir();
704
 
                        if (new_path != NULL) {
705
 
                            slashize_path(&new_path);
706
 
                            _dos_setdrive(current_drive, &num_available_drives);
707
 
                            if (new_path != NULL) {
708
 
                                struct file_list *new_fl;
709
 
 
710
 
                                new_fl = file_list_read(new_path, pattern);
711
 
                                if (new_fl != NULL) {
712
 
                                    file_list_free(fl);
713
 
                                    fl = new_fl;
714
 
                                    first_item = curr_item = 0;
715
 
                                    lib_free(return_path);
716
 
                                    return_path = new_path;
717
 
                                    need_update = 1;
718
 
                                    ioutil_chdir(return_path);
719
 
                                } else {
720
 
                                    lib_free(new_path);
721
 
                                }
722
 
                            }
723
 
                        } else {
724
 
                            _dos_setdrive(current_drive, &num_available_drives);                            tui_beep();
725
 
                        }
726
 
                    } else {
727
 
                        tui_beep();
728
 
                    }
729
 
                } else if (isprint(key) && str_len < 0x100) {
 
623
            case K_BackSpace:
 
624
                if (str_len > 1) {
730
625
                    int n;
731
 
                    str[str_len] = key;
732
 
                    n = file_list_find(fl, str, str_len + 1);
733
 
                    if (n < 0) {
734
 
                        tui_beep();
735
 
                    } else {
736
 
                        str_len++;
 
626
                    str_len--;
 
627
                    n = file_list_find(fl, str, str_len);
 
628
                    if (n >= 0) {
737
629
                        curr_item = n;
738
630
                        if (curr_item < first_item) {
739
631
                            first_item = curr_item;
743
635
                            need_update = 1;
744
636
                        }
745
637
                    }
746
 
                }
747
 
            }
748
 
            break;
 
638
                } else {
 
639
                    str_len = 0;
 
640
                    curr_item = 0;
 
641
                    if (first_item != 0) {
 
642
                        first_item = 0;
 
643
                        need_update = 1;
 
644
                    }
 
645
                }
 
646
                break;
 
647
            case ' ':
 
648
                if (contents_func != NULL && fl->items[curr_item].type != FT_DIR && browse_file_return != NULL) {
 
649
                    tui_display(0, tui_num_lines() - 1, tui_num_cols(), "");
 
650
                    *browse_file_return = tui_image_browser(fl->items[curr_item].name, contents_func, browse_file_number_return);
 
651
                    if (*browse_file_return != NULL) {
 
652
                        char *p = util_concat(return_path, fl->items[curr_item].name, NULL);
 
653
 
 
654
                        lib_free(return_path);
 
655
                        return_path = p;
 
656
                        tui_area_put(backing_store, x, y);
 
657
                        tui_area_free(backing_store);
 
658
                        return return_path;
 
659
                    }
 
660
                    need_update = 1;
 
661
                    break;
 
662
                } else {
 
663
                    tui_beep();
 
664
                }
 
665
            default:
 
666
                {
 
667
                    int drive_num;
 
668
 
 
669
                    drive_num = alt_key_to_drive_num(key);
 
670
 
 
671
                    if (drive_num > 0) {
 
672
                        /* `A-a' ... `A-z' change the current drive.  */
 
673
                        int num_available_drives;
 
674
                        int current_drive;
 
675
 
 
676
                        _dos_getdrive(&current_drive);
 
677
                        _dos_setdrive(current_drive, &num_available_drives);
 
678
                        if (drive_num <= num_available_drives) {
 
679
                            char *new_path;
 
680
 
 
681
                            /* FIXME: This is a hack...  Maybe there is a cleaner
 
682
                               way to do it, but for now I just don't know.  */
 
683
                            _dos_setdrive(drive_num, &num_available_drives);
 
684
                            new_path = ioutil_current_dir();
 
685
                            if (new_path != NULL) {
 
686
                                slashize_path(&new_path);
 
687
                                _dos_setdrive(current_drive, &num_available_drives);
 
688
                                if (new_path != NULL) {
 
689
                                    struct file_list *new_fl;
 
690
 
 
691
                                    new_fl = file_list_read(new_path, pattern);
 
692
                                    if (new_fl != NULL) {
 
693
                                        file_list_free(fl);
 
694
                                        fl = new_fl;
 
695
                                        first_item = curr_item = 0;
 
696
                                        lib_free(return_path);
 
697
                                        return_path = new_path;
 
698
                                        need_update = 1;
 
699
                                        ioutil_chdir(return_path);
 
700
                                    } else {
 
701
                                        lib_free(new_path);
 
702
                                    }
 
703
                                }
 
704
                            } else {
 
705
                                _dos_setdrive(current_drive, &num_available_drives);
 
706
                                tui_beep();
 
707
                            }
 
708
                        } else {
 
709
                            tui_beep();
 
710
                        }
 
711
                    } else if (isprint(key) && str_len < 0x100) {
 
712
                        int n;
 
713
 
 
714
                        str[str_len] = key;
 
715
                        n = file_list_find(fl, str, str_len + 1);
 
716
                        if (n < 0) {
 
717
                            tui_beep();
 
718
                        } else {
 
719
                            str_len++;
 
720
                            curr_item = n;
 
721
                            if (curr_item < first_item) {
 
722
                                first_item = curr_item;
 
723
                                need_update = 1;
 
724
                            } else if (first_item + num_files <= curr_item) {
 
725
                                first_item = curr_item - num_files + 1;
 
726
                                need_update = 1;
 
727
                            }
 
728
                        }
 
729
                    }
 
730
                }
 
731
                break;
749
732
        }
750
733
    }
751
734
}
752