Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/util-linux/fbset.c

    r1765 r2725  
    55 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 *
    99 * This is a from-scratch implementation of fbset; but the de facto fbset
     
    1818#define DEFAULTFBMODE "/etc/fb.modes"
    1919
     20/* Stuff stolen from the kernel's fb.h */
     21#define FB_ACTIVATE_ALL 64
    2022enum {
    21     OPT_CHANGE   = (1 << 0),
    22     OPT_INFO     = (1 << 1),
    23     OPT_READMODE = (1 << 2),
    24     OPT_ALL      = (1 << 9),
    25 
     23    FBIOGET_VSCREENINFO = 0x4600,
     24    FBIOPUT_VSCREENINFO = 0x4601
     25};
     26
     27struct fb_bitfield {
     28    uint32_t offset;                /* beginning of bitfield */
     29    uint32_t length;                /* length of bitfield */
     30    uint32_t msb_right;             /* !=0: Most significant bit is right */
     31};
     32struct fb_var_screeninfo {
     33    uint32_t xres;                  /* visible resolution */
     34    uint32_t yres;
     35    uint32_t xres_virtual;          /* virtual resolution */
     36    uint32_t yres_virtual;
     37    uint32_t xoffset;               /* offset from virtual to visible */
     38    uint32_t yoffset;               /* resolution */
     39
     40    uint32_t bits_per_pixel;
     41    uint32_t grayscale;             /* !=0 Graylevels instead of colors */
     42
     43    struct fb_bitfield red;         /* bitfield in fb mem if true color, */
     44    struct fb_bitfield green;       /* else only length is significant */
     45    struct fb_bitfield blue;
     46    struct fb_bitfield transp;      /* transparency */
     47
     48    uint32_t nonstd;                /* !=0 Non standard pixel format */
     49
     50    uint32_t activate;              /* see FB_ACTIVATE_x */
     51
     52    uint32_t height;                /* height of picture in mm */
     53    uint32_t width;                 /* width of picture in mm */
     54
     55    uint32_t accel_flags;           /* acceleration flags (hints) */
     56
     57    /* Timing: All values in pixclocks, except pixclock (of course) */
     58    uint32_t pixclock;              /* pixel clock in ps (pico seconds) */
     59    uint32_t left_margin;           /* time from sync to picture */
     60    uint32_t right_margin;          /* time from picture to sync */
     61    uint32_t upper_margin;          /* time from sync to picture */
     62    uint32_t lower_margin;
     63    uint32_t hsync_len;             /* length of horizontal sync */
     64    uint32_t vsync_len;             /* length of vertical sync */
     65    uint32_t sync;                  /* see FB_SYNC_x */
     66    uint32_t vmode;                 /* see FB_VMODE_x */
     67    uint32_t reserved[6];           /* Reserved for future compatibility */
     68};
     69
     70static void copy_if_gt0(uint32_t *src, uint32_t *dst, unsigned cnt)
     71{
     72    do {
     73        if ((int32_t) *src > 0)
     74            *dst = *src;
     75        src++;
     76        dst++;
     77    } while (--cnt);
     78}
     79
     80static NOINLINE void copy_changed_values(
     81        struct fb_var_screeninfo *base,
     82        struct fb_var_screeninfo *set)
     83{
     84    //if ((int32_t) set->xres > 0) base->xres = set->xres;
     85    //if ((int32_t) set->yres > 0) base->yres = set->yres;
     86    //if ((int32_t) set->xres_virtual > 0)   base->xres_virtual = set->xres_virtual;
     87    //if ((int32_t) set->yres_virtual > 0)   base->yres_virtual = set->yres_virtual;
     88    copy_if_gt0(&set->xres, &base->xres, 4);
     89
     90    if ((int32_t) set->bits_per_pixel > 0) base->bits_per_pixel = set->bits_per_pixel;
     91    //copy_if_gt0(&set->bits_per_pixel, &base->bits_per_pixel, 1);
     92
     93    //if ((int32_t) set->pixclock > 0)       base->pixclock = set->pixclock;
     94    //if ((int32_t) set->left_margin > 0)    base->left_margin = set->left_margin;
     95    //if ((int32_t) set->right_margin > 0)   base->right_margin = set->right_margin;
     96    //if ((int32_t) set->upper_margin > 0)   base->upper_margin = set->upper_margin;
     97    //if ((int32_t) set->lower_margin > 0)   base->lower_margin = set->lower_margin;
     98    //if ((int32_t) set->hsync_len > 0) base->hsync_len = set->hsync_len;
     99    //if ((int32_t) set->vsync_len > 0) base->vsync_len = set->vsync_len;
     100    //if ((int32_t) set->sync > 0)  base->sync = set->sync;
     101    //if ((int32_t) set->vmode > 0) base->vmode = set->vmode;
     102    copy_if_gt0(&set->pixclock, &base->pixclock, 9);
     103}
     104
     105
     106enum {
    26107    CMD_FB = 1,
    27108    CMD_DB = 2,
     
    36117    CMD_ALL = 11,
    37118    CMD_INFO = 12,
    38     CMD_CHANGE = 13,
     119    CMD_SHOW = 13,
     120    CMD_CHANGE = 14,
    39121
    40122#if ENABLE_FEATURE_FBSET_FANCY
     
    62144};
    63145
    64 static unsigned g_options;
    65 
    66 /* Stuff stolen from the kernel's fb.h */
    67 #define FB_ACTIVATE_ALL 64
    68 enum {
    69     FBIOGET_VSCREENINFO = 0x4600,
    70     FBIOPUT_VSCREENINFO = 0x4601
    71 };
    72 struct fb_bitfield {
    73     uint32_t offset;                /* beginning of bitfield */
    74     uint32_t length;        /* length of bitfield */
    75     uint32_t msb_right;             /* !=0: Most significant bit is right */
    76 };
    77 struct fb_var_screeninfo {
    78     uint32_t xres;                  /* visible resolution */
    79     uint32_t yres;
    80     uint32_t xres_virtual;          /* virtual resolution */
    81     uint32_t yres_virtual;
    82     uint32_t xoffset;               /* offset from virtual to visible */
    83     uint32_t yoffset;               /* resolution */
    84 
    85     uint32_t bits_per_pixel;
    86     uint32_t grayscale;             /* !=0 Graylevels instead of colors */
    87 
    88     struct fb_bitfield red;         /* bitfield in fb mem if true color, */
    89     struct fb_bitfield green;       /* else only length is significant */
    90     struct fb_bitfield blue;
    91     struct fb_bitfield transp;      /* transparency */
    92 
    93     uint32_t nonstd;                /* !=0 Non standard pixel format */
    94 
    95     uint32_t activate;              /* see FB_ACTIVATE_x */
    96 
    97     uint32_t height;                /* height of picture in mm */
    98     uint32_t width;                 /* width of picture in mm */
    99 
    100     uint32_t accel_flags;       /* acceleration flags (hints)   */
    101 
    102     /* Timing: All values in pixclocks, except pixclock (of course) */
    103     uint32_t pixclock;              /* pixel clock in ps (pico seconds) */
    104     uint32_t left_margin;           /* time from sync to picture */
    105     uint32_t right_margin;          /* time from picture to sync */
    106     uint32_t upper_margin;          /* time from sync to picture */
    107     uint32_t lower_margin;
    108     uint32_t hsync_len;             /* length of horizontal sync */
    109     uint32_t vsync_len;             /* length of vertical sync */
    110     uint32_t sync;                  /* see FB_SYNC_x */
    111     uint32_t vmode;                 /* see FB_VMODE_x */
    112     uint32_t reserved[6];           /* Reserved for future compatibility */
    113 };
    114 
    115 
    116146static const struct cmdoptions_t {
    117     const char name[10];
     147    const char name[9];
    118148    const unsigned char param_count;
    119149    const unsigned char code;
    120150} g_cmdoptions[] = {
    121     { "-fb", 1, CMD_FB },
    122     { "-db", 1, CMD_DB },
    123     { "-a", 0, CMD_ALL },
    124     { "-i", 0, CMD_INFO },
    125     { "-g", 5, CMD_GEOMETRY },
    126     { "-t", 7, CMD_TIMING },
    127     { "-accel", 1, CMD_ACCEL },
    128     { "-hsync", 1, CMD_HSYNC },
    129     { "-vsync", 1, CMD_VSYNC },
    130     { "-laced", 1, CMD_LACED },
    131     { "-double", 1, CMD_DOUBLE },
    132     { "-n", 0, CMD_CHANGE },
     151    /*"12345678" + NUL */
     152    { "fb"      , 1, CMD_FB       },
     153    { "db"      , 1, CMD_DB       },
     154    { "a"       , 0, CMD_ALL      },
     155    { "i"       , 0, CMD_INFO     },
     156    { "g"       , 5, CMD_GEOMETRY },
     157    { "t"       , 7, CMD_TIMING   },
     158    { "accel"   , 1, CMD_ACCEL    },
     159    { "hsync"   , 1, CMD_HSYNC    },
     160    { "vsync"   , 1, CMD_VSYNC    },
     161    { "laced"   , 1, CMD_LACED    },
     162    { "double"  , 1, CMD_DOUBLE   },
     163    { "show"    , 0, CMD_SHOW     },
     164    { "s"       , 0, CMD_SHOW     },
    133165#if ENABLE_FEATURE_FBSET_FANCY
    134     { "-all", 0, CMD_ALL },
    135     { "-xres", 1, CMD_XRES },
    136     { "-yres", 1, CMD_YRES },
    137     { "-vxres", 1, CMD_VXRES },
    138     { "-vyres", 1, CMD_VYRES },
    139     { "-depth", 1, CMD_DEPTH },
    140     { "-match", 0, CMD_MATCH },
    141     { "-geometry", 5, CMD_GEOMETRY },
    142     { "-pixclock", 1, CMD_PIXCLOCK },
    143     { "-left", 1, CMD_LEFT },
    144     { "-right", 1, CMD_RIGHT },
    145     { "-upper", 1, CMD_UPPER },
    146     { "-lower", 1, CMD_LOWER },
    147     { "-hslen", 1, CMD_HSLEN },
    148     { "-vslen", 1, CMD_VSLEN },
    149     { "-timings", 7, CMD_TIMING },
    150     { "-csync", 1, CMD_CSYNC },
    151     { "-gsync", 1, CMD_GSYNC },
    152     { "-extsync", 1, CMD_EXTSYNC },
    153     { "-bcast", 1, CMD_BCAST },
    154     { "-rgba", 1, CMD_RGBA },
    155     { "-step", 1, CMD_STEP },
    156     { "-move", 1, CMD_MOVE },
    157 #endif
    158     { "", 0, 0 }
    159 };
    160 
    161 #if ENABLE_FEATURE_FBSET_READMODE
     166    { "all"     , 0, CMD_ALL      },
     167    { "xres"    , 1, CMD_XRES     },
     168    { "yres"    , 1, CMD_YRES     },
     169    { "vxres"   , 1, CMD_VXRES    },
     170    { "vyres"   , 1, CMD_VYRES    },
     171    { "depth"   , 1, CMD_DEPTH    },
     172    { "match"   , 0, CMD_MATCH    },
     173    { "geometry", 5, CMD_GEOMETRY },
     174    { "pixclock", 1, CMD_PIXCLOCK },
     175    { "left"    , 1, CMD_LEFT     },
     176    { "right"   , 1, CMD_RIGHT    },
     177    { "upper"   , 1, CMD_UPPER    },
     178    { "lower"   , 1, CMD_LOWER    },
     179    { "hslen"   , 1, CMD_HSLEN    },
     180    { "vslen"   , 1, CMD_VSLEN    },
     181    { "timings" , 7, CMD_TIMING   },
     182    { "csync"   , 1, CMD_CSYNC    },
     183    { "gsync"   , 1, CMD_GSYNC    },
     184    { "extsync" , 1, CMD_EXTSYNC  },
     185    { "bcast"   , 1, CMD_BCAST    },
     186    { "rgba"    , 1, CMD_RGBA     },
     187    { "step"    , 1, CMD_STEP     },
     188    { "move"    , 1, CMD_MOVE     },
     189#endif
     190};
     191
    162192/* taken from linux/fb.h */
    163193enum {
    164     FB_VMODE_INTERLACED = 1,    /* interlaced   */
    165     FB_VMODE_DOUBLE = 2,    /* double scan */
    166     FB_SYNC_HOR_HIGH_ACT = 1,   /* horizontal sync high active  */
    167     FB_SYNC_VERT_HIGH_ACT = 2,  /* vertical sync high active    */
    168     FB_SYNC_EXT = 4,    /* external sync        */
    169     FB_SYNC_COMP_HIGH_ACT = 8   /* composite sync high active   */
    170 };
    171 #endif
    172 
    173 static int readmode(struct fb_var_screeninfo *base, const char *fn,
     194    FB_SYNC_HOR_HIGH_ACT = 1,       /* horizontal sync high active */
     195    FB_SYNC_VERT_HIGH_ACT = 2,      /* vertical sync high active */
     196#if ENABLE_FEATURE_FBSET_READMODE
     197    FB_VMODE_INTERLACED = 1,        /* interlaced */
     198    FB_VMODE_DOUBLE = 2,            /* double scan */
     199    FB_SYNC_EXT = 4,                /* external sync */
     200    FB_SYNC_COMP_HIGH_ACT = 8,      /* composite sync high active */
     201#endif
     202};
     203
     204#if ENABLE_FEATURE_FBSET_READMODE
     205static void ss(uint32_t *x, uint32_t flag, char *buf, const char *what)
     206{
     207    if (strcmp(buf, what) == 0)
     208        *x &= ~flag;
     209    else
     210        *x |= flag;
     211}
     212
     213/* Mode db file contains mode definitions like this:
     214 * mode "800x600-48-lace"
     215 *     # D: 36.00 MHz, H: 33.835 kHz, V: 96.39 Hz
     216 *     geometry 800 600 800 600 8
     217 *     timings 27778 56 80 79 11 128 12
     218 *     laced true
     219 *     hsync high
     220 *     vsync high
     221 * endmode
     222 */
     223static int read_mode_db(struct fb_var_screeninfo *base, const char *fn,
    174224                    const char *mode)
    175225{
    176 #if ENABLE_FEATURE_FBSET_READMODE
    177     FILE *f;
    178     char buf[256];
    179     char *p = buf;
    180 
    181     f = xfopen(fn, "r");
    182     while (!feof(f)) {
    183         fgets(buf, sizeof(buf), f);
    184         if (!(p = strstr(buf, "mode ")) && !(p = strstr(buf, "mode\t")))
     226    char *token[2], *p, *s;
     227    parser_t *parser = config_open(fn);
     228
     229    while (config_read(parser, token, 2, 1, "# \t\r", PARSE_NORMAL)) {
     230        if (strcmp(token[0], "mode") != 0 || !token[1])
    185231            continue;
    186         p += 5;
    187         if (!(p = strstr(buf, mode)))
     232        p = strstr(token[1], mode);
     233        if (!p)
    188234            continue;
    189         p += strlen(mode);
    190         if (!isspace(*p) && (*p != 0) && (*p != '"')
    191                 && (*p != '\r') && (*p != '\n'))
    192             continue;   /* almost, but not quite */
    193 
    194         while (!feof(f)) {
    195             fgets(buf, sizeof(buf), f);
    196             if ((p = strstr(buf, "geometry "))) {
    197                 p += 9;
    198                 /* FIXME: catastrophic on arches with 64bit ints */
     235        s = p + strlen(mode);
     236        //bb_info_msg("CHECK[%s][%s][%d]", mode, p-1, *s);
     237        /* exact match? */
     238        if (((!*s || isspace(*s)) && '"' != s[-1]) /* end-of-token */
     239         || ('"' == *s && '"' == p[-1]) /* ends with " but starts with " too! */
     240        ) {
     241            //bb_info_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s));
     242            break;
     243        }
     244    }
     245
     246    if (!token[0])
     247        return 0;
     248
     249    while (config_read(parser, token, 2, 1, "# \t", PARSE_NORMAL)) {
     250        int i;
     251
     252//bb_info_msg("???[%s][%s]", token[0], token[1]);
     253        if (strcmp(token[0], "endmode") == 0) {
     254//bb_info_msg("OK[%s]", mode);
     255            return 1;
     256        }
     257        p = token[1];
     258        i = index_in_strings(
     259            "geometry\0timings\0interlaced\0double\0vsync\0hsync\0csync\0extsync\0",
     260            token[0]);
     261        switch (i) {
     262        case 0:
     263            if (sizeof(int) == sizeof(base->xres)) {
    199264                sscanf(p, "%d %d %d %d %d",
    200                     &(base->xres), &(base->yres),
    201                     &(base->xres_virtual), &(base->yres_virtual),
    202                     &(base->bits_per_pixel));
    203             } else if ((p = strstr(buf, "timings "))) {
    204                 p += 8;
     265                    &base->xres, &base->yres,
     266                    &base->xres_virtual, &base->yres_virtual,
     267                    &base->bits_per_pixel);
     268            } else {
     269                int base_xres, base_yres;
     270                int base_xres_virtual, base_yres_virtual;
     271                int base_bits_per_pixel;
     272                sscanf(p, "%d %d %d %d %d",
     273                    &base_xres, &base_yres,
     274                    &base_xres_virtual, &base_yres_virtual,
     275                    &base_bits_per_pixel);
     276                base->xres = base_xres;
     277                base->yres = base_yres;
     278                base->xres_virtual = base_xres_virtual;
     279                base->yres_virtual = base_yres_virtual;
     280                base->bits_per_pixel = base_bits_per_pixel;
     281            }
     282//bb_info_msg("GEO[%s]", p);
     283            break;
     284        case 1:
     285            if (sizeof(int) == sizeof(base->xres)) {
    205286                sscanf(p, "%d %d %d %d %d %d %d",
    206                     &(base->pixclock),
    207                     &(base->left_margin), &(base->right_margin),
    208                     &(base->upper_margin), &(base->lower_margin),
    209                     &(base->hsync_len), &(base->vsync_len));
    210             } else if ((p = strstr(buf, "laced "))) {
    211                 //p += 6;
    212                 if (strstr(buf, "false")) {
    213                     base->vmode &= ~FB_VMODE_INTERLACED;
    214                 } else {
    215                     base->vmode |= FB_VMODE_INTERLACED;
    216                 }
    217             } else if ((p = strstr(buf, "double "))) {
    218                 //p += 7;
    219                 if (strstr(buf, "false")) {
    220                     base->vmode &= ~FB_VMODE_DOUBLE;
    221                 } else {
    222                     base->vmode |= FB_VMODE_DOUBLE;
    223                 }
    224             } else if ((p = strstr(buf, "vsync "))) {
    225                 //p += 6;
    226                 if (strstr(buf, "low")) {
    227                     base->sync &= ~FB_SYNC_VERT_HIGH_ACT;
    228                 } else {
    229                     base->sync |= FB_SYNC_VERT_HIGH_ACT;
    230                 }
    231             } else if ((p = strstr(buf, "hsync "))) {
    232                 //p += 6;
    233                 if (strstr(buf, "low")) {
    234                     base->sync &= ~FB_SYNC_HOR_HIGH_ACT;
    235                 } else {
    236                     base->sync |= FB_SYNC_HOR_HIGH_ACT;
    237                 }
    238             } else if ((p = strstr(buf, "csync "))) {
    239                 //p += 6;
    240                 if (strstr(buf, "low")) {
    241                     base->sync &= ~FB_SYNC_COMP_HIGH_ACT;
    242                 } else {
    243                     base->sync |= FB_SYNC_COMP_HIGH_ACT;
    244                 }
    245             } else if ((p = strstr(buf, "extsync "))) {
    246                 //p += 8;
    247                 if (strstr(buf, "false")) {
    248                     base->sync &= ~FB_SYNC_EXT;
    249                 } else {
    250                     base->sync |= FB_SYNC_EXT;
    251                 }
     287                    &base->pixclock,
     288                    &base->left_margin, &base->right_margin,
     289                    &base->upper_margin, &base->lower_margin,
     290                    &base->hsync_len, &base->vsync_len);
     291            } else {
     292                int base_pixclock;
     293                int base_left_margin, base_right_margin;
     294                int base_upper_margin, base_lower_margin;
     295                int base_hsync_len, base_vsync_len;
     296                sscanf(p, "%d %d %d %d %d %d %d",
     297                    &base_pixclock,
     298                    &base_left_margin, &base_right_margin,
     299                    &base_upper_margin, &base_lower_margin,
     300                    &base_hsync_len, &base_vsync_len);
     301                base->pixclock = base_pixclock;
     302                base->left_margin = base_left_margin;
     303                base->right_margin = base_right_margin;
     304                base->upper_margin = base_upper_margin;
     305                base->lower_margin = base_lower_margin;
     306                base->hsync_len = base_hsync_len;
     307                base->vsync_len = base_vsync_len;
    252308            }
    253 
    254             if (strstr(buf, "endmode"))
    255                 return 1;
    256         }
    257     }
    258 #else
    259     bb_error_msg("mode reading not compiled in");
    260 #endif
     309//bb_info_msg("TIM[%s]", p);
     310            break;
     311        case 2:
     312        case 3: {
     313            static const uint32_t syncs[] = {FB_VMODE_INTERLACED, FB_VMODE_DOUBLE};
     314            ss(&base->vmode, syncs[i-2], p, "false");
     315//bb_info_msg("VMODE[%s]", p);
     316            break;
     317        }
     318        case 4:
     319        case 5:
     320        case 6: {
     321            static const uint32_t syncs[] = {FB_SYNC_VERT_HIGH_ACT, FB_SYNC_HOR_HIGH_ACT, FB_SYNC_COMP_HIGH_ACT};
     322            ss(&base->sync, syncs[i-4], p, "low");
     323//bb_info_msg("SYNC[%s]", p);
     324            break;
     325        }
     326        case 7:
     327            ss(&base->sync, FB_SYNC_EXT, p, "false");
     328//bb_info_msg("EXTSYNC[%s]", p);
     329            break;
     330        }
     331    }
    261332    return 0;
    262333}
    263 
    264 static inline void setmode(struct fb_var_screeninfo *base,
    265                     struct fb_var_screeninfo *set)
    266 {
    267     if ((int) set->xres > 0)
    268         base->xres = set->xres;
    269     if ((int) set->yres > 0)
    270         base->yres = set->yres;
    271     if ((int) set->xres_virtual > 0)
    272         base->xres_virtual = set->xres_virtual;
    273     if ((int) set->yres_virtual > 0)
    274         base->yres_virtual = set->yres_virtual;
    275     if ((int) set->bits_per_pixel > 0)
    276         base->bits_per_pixel = set->bits_per_pixel;
    277 }
    278 
    279 static inline void showmode(struct fb_var_screeninfo *v)
     334#endif
     335
     336static NOINLINE void showmode(struct fb_var_screeninfo *v)
    280337{
    281338    double drate = 0, hrate = 0, vrate = 0;
     
    307364}
    308365
    309 #ifdef STANDALONE
    310 int main(int argc, char **argv)
    311 #else
    312 int fbset_main(int argc, char **argv);
     366int fbset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    313367int fbset_main(int argc, char **argv)
    314 #endif
    315 {
    316     struct fb_var_screeninfo var, varset;
     368{
     369    enum {
     370        OPT_CHANGE   = (1 << 0),
     371        OPT_SHOW     = (1 << 1),
     372        OPT_READMODE = (1 << 2),
     373        OPT_ALL      = (1 << 9),
     374    };
     375    struct fb_var_screeninfo var_old, var_set;
    317376    int fh, i;
     377    unsigned options = 0;
     378
    318379    const char *fbdev = DEFAULTFBDEV;
    319380    const char *modefile = DEFAULTFBMODE;
    320     char *thisarg, *mode = NULL;
    321 
    322     memset(&varset, 0xFF, sizeof(varset));
     381    char *thisarg;
     382    char *mode = mode; /* for compiler */
     383
     384    memset(&var_set, 0xff, sizeof(var_set)); /* set all to -1 */
    323385
    324386    /* parse cmd args.... why do they have to make things so difficult? */
    325387    argv++;
    326388    argc--;
    327     for (; argc > 0 && (thisarg = *argv); argc--, argv++) {
    328         for (i = 0; g_cmdoptions[i].name[0]; i++) {
    329             if (strcmp(thisarg, g_cmdoptions[i].name))
     389    for (; argc > 0 && (thisarg = *argv) != NULL; argc--, argv++) {
     390        if (thisarg[0] == '-') for (i = 0; i < ARRAY_SIZE(g_cmdoptions); i++) {
     391            if (strcmp(thisarg + 1, g_cmdoptions[i].name) != 0)
    330392                continue;
    331             if (argc-1 < g_cmdoptions[i].param_count)
     393            if (argc <= g_cmdoptions[i].param_count)
    332394                bb_show_usage();
    333395
     
    339401                modefile = argv[1];
    340402                break;
     403            case CMD_ALL:
     404                options |= OPT_ALL;
     405                break;
     406            case CMD_SHOW:
     407                options |= OPT_SHOW;
     408                break;
    341409            case CMD_GEOMETRY:
    342                 varset.xres = xatou32(argv[1]);
    343                 varset.yres = xatou32(argv[2]);
    344                 varset.xres_virtual = xatou32(argv[3]);
    345                 varset.yres_virtual = xatou32(argv[4]);
    346                 varset.bits_per_pixel = xatou32(argv[5]);
     410                var_set.xres = xatou32(argv[1]);
     411                var_set.yres = xatou32(argv[2]);
     412                var_set.xres_virtual = xatou32(argv[3]);
     413                var_set.yres_virtual = xatou32(argv[4]);
     414                var_set.bits_per_pixel = xatou32(argv[5]);
    347415                break;
    348416            case CMD_TIMING:
    349                 varset.pixclock = xatou32(argv[1]);
    350                 varset.left_margin = xatou32(argv[2]);
    351                 varset.right_margin = xatou32(argv[3]);
    352                 varset.upper_margin = xatou32(argv[4]);
    353                 varset.lower_margin = xatou32(argv[5]);
    354                 varset.hsync_len = xatou32(argv[6]);
    355                 varset.vsync_len = xatou32(argv[7]);
    356                 break;
    357             case CMD_ALL:
    358                 g_options |= OPT_ALL;
    359                 break;
    360             case CMD_CHANGE:
    361                 g_options |= OPT_CHANGE;
     417                var_set.pixclock = xatou32(argv[1]);
     418                var_set.left_margin = xatou32(argv[2]);
     419                var_set.right_margin = xatou32(argv[3]);
     420                var_set.upper_margin = xatou32(argv[4]);
     421                var_set.lower_margin = xatou32(argv[5]);
     422                var_set.hsync_len = xatou32(argv[6]);
     423                var_set.vsync_len = xatou32(argv[7]);
     424                break;
     425            case CMD_ACCEL:
     426                break;
     427            case CMD_HSYNC:
     428                var_set.sync |= FB_SYNC_HOR_HIGH_ACT;
     429                break;
     430            case CMD_VSYNC:
     431                var_set.sync |= FB_SYNC_VERT_HIGH_ACT;
    362432                break;
    363433#if ENABLE_FEATURE_FBSET_FANCY
    364434            case CMD_XRES:
    365                 varset.xres = xatou32(argv[1]);
     435                var_set.xres = xatou32(argv[1]);
    366436                break;
    367437            case CMD_YRES:
    368                 varset.yres = xatou32(argv[1]);
     438                var_set.yres = xatou32(argv[1]);
    369439                break;
    370440            case CMD_DEPTH:
    371                 varset.bits_per_pixel = xatou32(argv[1]);
    372                 break;
    373 #endif
     441                var_set.bits_per_pixel = xatou32(argv[1]);
     442                break;
     443#endif
     444            }
     445            switch (g_cmdoptions[i].code) {
     446            case CMD_FB:
     447            case CMD_DB:
     448            case CMD_ALL:
     449            case CMD_SHOW:
     450                break;
     451            default:
     452                /* other commands imply changes */
     453                options |= OPT_CHANGE;
    374454            }
    375455            argc -= g_cmdoptions[i].param_count;
    376456            argv += g_cmdoptions[i].param_count;
    377             break;
    378         }
    379         if (!g_cmdoptions[i].name[0]) {
    380             if (argc != 1)
    381                 bb_show_usage();
    382             mode = *argv;
    383             g_options |= OPT_READMODE;
    384         }
     457            goto contin;
     458        }
     459        if (!ENABLE_FEATURE_FBSET_READMODE || argc != 1)
     460            bb_show_usage();
     461        mode = *argv;
     462        options |= OPT_READMODE;
     463 contin: ;
    385464    }
    386465
    387466    fh = xopen(fbdev, O_RDONLY);
    388     xioctl(fh, FBIOGET_VSCREENINFO, &var);
    389     if (g_options & OPT_READMODE) {
    390         if (!readmode(&var, modefile, mode)) {
     467    xioctl(fh, FBIOGET_VSCREENINFO, &var_old);
     468
     469    if (options & OPT_READMODE) {
     470#if ENABLE_FEATURE_FBSET_READMODE
     471        if (!read_mode_db(&var_old, modefile, mode)) {
    391472            bb_error_msg_and_die("unknown video mode '%s'", mode);
    392473        }
    393     }
    394 
    395     setmode(&var, &varset);
    396     if (g_options & OPT_CHANGE) {
    397         if (g_options & OPT_ALL)
    398             var.activate = FB_ACTIVATE_ALL;
    399         xioctl(fh, FBIOPUT_VSCREENINFO, &var);
    400     }
    401     showmode(&var);
    402     /* Don't close the file, as exiting will take care of that */
    403     /* close(fh); */
     474#endif
     475    }
     476
     477    if (options & OPT_CHANGE) {
     478        copy_changed_values(&var_old, &var_set);
     479        if (options & OPT_ALL)
     480            var_old.activate = FB_ACTIVATE_ALL;
     481        xioctl(fh, FBIOPUT_VSCREENINFO, &var_old);
     482    }
     483
     484    if (options == 0 || (options & OPT_SHOW))
     485        showmode(&var_old);
     486
     487    if (ENABLE_FEATURE_CLEAN_UP)
     488        close(fh);
    404489
    405490    return EXIT_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.