⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfsel.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*         ______   ___    ___  *        /\  _  \ /\_ \  /\_ \  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\ *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \ *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ *                                           /\____/ *                                           \_/__/ * *      The file selector. * *      By Shawn Hargreaves. * *      Guilherme Silveira and Theuzifan Sumachingun both independently  *      modified it to only list valid drive letters. * *      Peter Pavlovic modified it not to list the logical drives, such *      as the b: drive assigned as a logical drive for a: on single *      floppy disk drive equipped systems and improved the browsing *      through directories. * *      Peter Wang and Eric Botcazou modified it to stretch to screen and *      font sizes. * *      See readme.txt for copyright information. */#include <allegro.h>// These 2 files must be included before raine.h because of a collision !!!#if defined ALLEGRO_WINDOWS   #include "winalleg.h"#endif#include <errno.h>#include <stdlib.h>#include <string.h>#ifndef RAINE_UNIX#ifndef RAINE_WIN32#include <unistd.h>#endif#endif#include <sys/stat.h>#include <limits.h>#include <ctype.h>#include <fcntl.h>#ifdef DJGPP#include <dir.h>#endif#include "raine.h"#include "rgui.h"#include "rguiproc.h"#ifndef _USE_LFN#define _USE_LFN  0#endif#if (DEVICE_SEPARATOR != 0) && (DEVICE_SEPARATOR != '\0')   #define HAVE_DIR_LIST#endifstatic int fs_edit_proc(int, DIALOG *, int );static int fs_flist_proc(int, DIALOG *, int );static char *fs_flist_getter(int, int *);#ifdef HAVE_DIR_LISTstatic int fs_dlist_proc(int, DIALOG *, int );static char *fs_dlist_getter(int, int *);#endif#define FLIST_SIZE      2048typedef struct FLIST{   char dir[512];   int size;   char *name[FLIST_SIZE];} FLIST;static FLIST *flist = NULL;static char updir[1024];static char *fext = NULL;DIALOG file_selector[] ={#ifdef HAVE_DIR_LIST   /* (dialog proc)     (x)   (y)   (w)   (h)   (fg)  (bg)  (key) (flags)  (d1)  (d2)  (dp) */   { d_raine_window_proc,0,   0,    305,  161,  GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  0,    0,       0,    0,    NULL },   { x_ctext_proc,      152,  1,    1,    1,    GUI_COL_TEXT_1,    GUI_BOX_COL_MIDDLE,    0,    0,       0,    0,    NULL,             NULL, NULL  },   { x_raine_button_proc,8,   128,  48,   16,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  'O',  D_EXIT,  0,    0,    "&Okay" },   { x_raine_button_proc,64,  128,  48,   16,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  27,   D_EXIT,  0,    0,    "Cancel" },   { fs_edit_proc,      8,    116,  248,  8,    GUI_COL_TEXT_1,  253,  0,    0,       79,   0,    NULL },   { fs_flist_proc,     80,   20,   176,  92,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  0,    D_EXIT,  0,    0,    fs_flist_getter },   { fs_dlist_proc,     8,    20,   64,   92,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  0,    D_EXIT,  0,    0,    fs_dlist_getter },   { d_yield_proc,      0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL,             NULL, NULL  },#else   { d_raine_window_proc,0,   0,    305,  161,  GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  0,    0,       0,    0,    NULL },   { x_ctext_proc,      152,  1,    1,    1,    GUI_COL_TEXT_1,    GUI_BOX_COL_MIDDLE,    0,    0,       0,    0,    NULL,             NULL, NULL  },   { x_raine_button_proc,8,   128,  48,   16,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  'O',  D_EXIT,  0,    0,    "&Okay" },   { x_raine_button_proc,64,  128,  48,   16,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  27,   D_EXIT,  0,    0,    "Cancel" },   { fs_edit_proc,      8,    116,  248,  8,    GUI_COL_TEXT_1,  253,  0,    0,       79,   0,    NULL },   { fs_flist_proc,     80,   20,   176,  92,   GUI_COL_TEXT_1,  GUI_BOX_COL_MIDDLE,  0,    D_EXIT,  0,    0,    fs_flist_getter },   { d_yield_proc,      0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL,             NULL, NULL  },#endif   { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }};#define FS_FRAME	0#define FS_MESSAGE      1#define FS_OK           2#define FS_CANCEL       3#define FS_EDIT         4#define FS_FILES        5#ifdef HAVE_DIR_LIST       /* not all platforms need a directory list */#define FS_DISKS        6#define FS_YIELD        7/* drive_exists: *  Checks whether the specified drive is valid. */static int drive_exists(int x){   #ifdef ALLEGRO_DOS      /* DOS implementation */      unsigned int old;      int ret = FALSE;      __dpmi_regs r;      /* get actual drive */      r.h.ah = 0x19;      __dpmi_int(0x21, &r);      old = r.h.al;      /* see if drive x is assigned as a valid drive */      r.h.ah = 0x0E;      r.h.dl = x;      __dpmi_int(0x21, &r);      r.h.ah = 0x19;      __dpmi_int(0x21, &r);      if (r.h.al == x) {	 /* ok, now check if it is a logical drive or not... */	 r.x.ax = 0x440E;	 r.h.bl = x+1;	 __dpmi_int(0x21, &r);	 if ((r.x.flags & 1) ||        /* call failed */	     (r.h.al == 0) ||          /* has no logical drives */	     (r.h.al == (x+1)))        /* not a logical drive */	    ret = TRUE;      }      /* now we set the old drive */      r.h.ah = 0x0E;      r.h.dl = old;      __dpmi_int(0x21, &r);      return ret;   #elif defined ALLEGRO_WINDOWS      /* Windows implementation */      return GetLogicalDrives() & (1 << x);   #elif defined ALLEGRO_MPW      /* MacOs implementation */      return GetLogicalDrives() & (1 << x);   #else      /* unknown platform */      return TRUE;   #endif}/* count_disks: *  Counts the number of valid drives. */static int count_disks(){   int c, i;   c = 0;   for (i=0; i<26; i++)      if (drive_exists(i))	 c++;   return c;}/* get_x_drive: *  Returns the drive letter matching the specified list index. */static int get_x_drive(int index){   int c, i;   c = 0;   for (i=0; i<26; i++) {      if (drive_exists(i)) {	 c++;	 if (c==index)	    return i;      }   }   return -1;}/* fs_dlist_getter: *  Listbox data getter routine for the file selector disk list. */static char *fs_dlist_getter(int index, int *list_size){   static char d[8];   int pos, c;   if (index < 0) {      if (list_size)	 *list_size = count_disks();      return NULL;   }   c = 'A' + get_x_drive(index+1);   if ((c < 'A') || (c > 'Z'))      c = 'C';   pos = usetc(d, c);   pos += usetc(d+pos, DEVICE_SEPARATOR);   pos += usetc(d+pos, OTHER_PATH_SEPARATOR);   usetc(d+pos, 0);   return d;}/* fs_dlist_proc: *  Dialog procedure for the file selector disk list. */static int fs_dlist_proc(int msg, DIALOG *d, int c){   char *s = file_selector[FS_EDIT].dp;   int ret, i, temp;   if (msg == MSG_START) {      d->d1 = d->d2 = 0;      temp = utoupper(ugetc(s));      if (((temp >= 'A') && (temp <= 'Z')) && (ugetat(s, 1) == DEVICE_SEPARATOR)) {	 temp -= 'A';	 for (i=0; i<temp; i++)	    if (drive_exists(i))	       d->d1++;      }   }   ret = d_text_list_proc(msg, d, c);   if (ret == D_CLOSE) {      temp = 'A' + get_x_drive(d->d1+1);      if ((temp < 'A') || (temp > 'Z'))	 temp = 'C';      s += usetc(s, temp);      s += usetc(s, DEVICE_SEPARATOR);      s += usetc(s, OTHER_PATH_SEPARATOR);      usetc(s, 0);      scare_mouse();      SEND_MESSAGE(file_selector+FS_FILES, MSG_START, 0);      SEND_MESSAGE(file_selector+FS_FILES, MSG_DRAW, 0);      SEND_MESSAGE(file_selector+FS_EDIT, MSG_START, 0);      SEND_MESSAGE(file_selector+FS_EDIT, MSG_DRAW, 0);      unscare_mouse();      return D_O_K;   }   return ret;}#else#define FS_YIELD        6#endif      /* HAVE_DIR_LIST *//* fs_edit_proc: *  Dialog procedure for the file selector editable string. */static int fs_edit_proc(int msg, DIALOG *d, int c){   char *s = d->dp;   int list_size;   int found = 0;   char b[512];   int ch, attr;   int i;   if (msg == MSG_START) {      fix_filename_path(b, s, sizeof(b));      ustrcpy(s, b);   }   if (msg == MSG_KEY) {      if ((!ugetc(s)) || (ugetat(s, -1) == DEVICE_SEPARATOR))	 ustrcat(s, uconvert_ascii("./", NULL));      fix_filename_path(b, s, sizeof(b));      ustrcpy(s, b);      ch = ugetat(s, -1);      if ((ch != '/') && (ch != OTHER_PATH_SEPARATOR)) {	 if (file_exists(s, FA_RDONLY | FA_HIDDEN | FA_DIREC, &attr)) {	    if (attr & FA_DIREC)	       put_backslash(s);	    else	       return D_CLOSE;	 }	 else	    return D_CLOSE;      }      scare_mouse();      SEND_MESSAGE(file_selector+FS_FILES, MSG_START, 0);      /* did we `cd ..' ? */      if (ustrlen(updir)) {	 /* now we have to find a directory name equal to updir */	 for (i = 0; i<flist->size; i++) {	    if (!ustrcmp(updir, flist->name[i])) {  /* we got it ! */	       file_selector[FS_FILES].d1 = i;	       /* we have to know the number of visible lines in the filelist */	       /* -1 to avoid an off-by-one problem */               list_size = (file_selector[FS_FILES].h-4) / text_height(font) - 1;               if (i>list_size)		  file_selector[FS_FILES].d2 = i-list_size;	       else		  file_selector[FS_FILES].d2 = 0;               found = 1;	       break;  /* ok, our work is done... */	    }	 }	 /* by some strange reason, we didn't find the old directory... */         if (!found) {            file_selector[FS_FILES].d1 = 0;            file_selector[FS_FILES].d2 = 0;         }      }      /* and continue... */      SEND_MESSAGE(file_selector+FS_FILES, MSG_DRAW, 0);      SEND_MESSAGE(d, MSG_START, 0);      SEND_MESSAGE(d, MSG_DRAW, 0);      unscare_mouse();      return D_O_K;   }   if (msg == MSG_UCHAR) {      if ((c >= 'a') && (c <= 'z')) {	 if (!ALLEGRO_LFN)	    c = utoupper(c);      }      else if (c == '/') {	 c = OTHER_PATH_SEPARATOR;      }      else if (ALLEGRO_LFN) {	 if ((c > 127) || (c < 32))	    return D_O_K;      }      else {	 if ((c != OTHER_PATH_SEPARATOR) && (c != '_') &&	     (c != DEVICE_SEPARATOR) && (c != '.') &&	     ((c < 'A') || (c > 'Z')) && ((c < '0') || (c > '9')))	    return D_O_K;      }   }   return x_edit_proc(msg, d, c); }/* ustrfilecmp: *  ustricmp for filenames: makes sure that eg "foo.bar" comes before *  "foo-1.bar", and also that "foo9.bar" comes before "foo10.bar". */static int ustrfilecmp(AL_CONST char *s1, AL_CONST char *s2){   int c1, c2;   int x1, x2;   char *t1, *t2;   for (;;) {      c1 = utolower(ugetxc(&s1));      c2 = utolower(ugetxc(&s2));      if ((c1 >= '0') && (c1 <= '9') && (c2 >= '0') && (c2 <= '9')) {	 x1 = ustrtol(s1 - ucwidth(c1), &t1, 10);	 x2 = ustrtol(s2 - ucwidth(c2), &t2, 10);	 if (x1 != x2)	    return x1 - x2;	 else if (t1 - s1 != t2 - s2)	    return (t2 - s2) - (t1 - s1);	 s1 = t1;	 s2 = t2;      }      else if (c1 != c2) {	 if (!c1)	    return -1;	 else if (!c2)	    return 1;	 else if (c1 == '.')	    return -1;	 else if (c2 == '.')	    return 1;	 return c1 - c2;      }      if (!c1)	 return 0;   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -