From 0a26e076e10a3c7461d59c830cdc10688d66824f Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 6 Feb 2013 13:08:58 -0800 Subject: Bug #11397: check that numeric --orientation arguments are in range The only valid parameters to -o (--orientation) are 0, 1, 2, 3, normal, left, inverted, and right. xrandr converts the strings to numbers and then checks that they're within range, but doesn't validate them if it was numeric to begin with. Move the range check outside of the if statement so that out-of-range numeric values are rejected properly. Signed-off-by: Aaron Plattner Reviewed-by: Daniel Dadap --- xrandr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrandr.c b/xrandr.c index b0e8cec..926bc68 100644 --- a/xrandr.c +++ b/xrandr.c @@ -2579,8 +2579,8 @@ main (int argc, char **argv) for (dirind = 0; dirind < 4; dirind++) { if (strcmp (direction[dirind], argv[i]) == 0) break; } - if ((dirind < 0) || (dirind > 3)) usage(); } + if ((dirind < 0) || (dirind > 3)) usage(); rot = dirind; setit = True; action_requested = True; -- cgit v1.2.3 From b2f0bd198b1116e45389a6628b657b722b4102a4 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 6 Feb 2013 14:11:23 -0800 Subject: Bug #14118: print usage() to stdout, proper errors for bad arguments Print the usage() text to stdout instead of stderr, and then only if -help is specified. Also allow --help for consistency. For other command line syntax errors, introduce a new helper function argerr() that prints errors of the form xrandr: %s Try './xrandr --help' for more information. and exits. Use that to print proper error messages. Signed-off-by: Aaron Plattner Reviewed-by: Daniel Dadap --- xrandr.c | 297 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 153 insertions(+), 144 deletions(-) diff --git a/xrandr.c b/xrandr.c index 926bc68..a5a9fd0 100644 --- a/xrandr.c +++ b/xrandr.c @@ -92,68 +92,65 @@ static const struct { { NULL, 0 } }; -static void _X_NORETURN +static void usage(void) { - fprintf(stderr, "usage: %s [options]\n", program_name); - fprintf(stderr, " where options are:\n"); - fprintf(stderr, " -display or -d \n"); - fprintf(stderr, " -help\n"); - fprintf(stderr, " -o \n"); - fprintf(stderr, " or --orientation \n"); - fprintf(stderr, " -q or --query\n"); - fprintf(stderr, " -s /x or --size /x\n"); - fprintf(stderr, " -r or --rate or --refresh \n"); - fprintf(stderr, " -v or --version\n"); - fprintf(stderr, " -x (reflect in x)\n"); - fprintf(stderr, " -y (reflect in y)\n"); - fprintf(stderr, " --screen \n"); - fprintf(stderr, " --verbose\n"); - fprintf(stderr, " --current\n"); - fprintf(stderr, " --dryrun\n"); - fprintf(stderr, " --nograb\n"); - fprintf(stderr, " --prop or --properties\n"); - fprintf(stderr, " --fb x\n"); - fprintf(stderr, " --fbmm x\n"); - fprintf(stderr, " --dpi /\n"); - fprintf(stderr, " --output \n"); - fprintf(stderr, " --auto\n"); - fprintf(stderr, " --mode \n"); - fprintf(stderr, " --preferred\n"); - fprintf(stderr, " --pos x\n"); - fprintf(stderr, " --rate or --refresh \n"); - fprintf(stderr, " --reflect normal,x,y,xy\n"); - fprintf(stderr, " --rotate normal,inverted,left,right\n"); - fprintf(stderr, " --left-of \n"); - fprintf(stderr, " --right-of \n"); - fprintf(stderr, " --above \n"); - fprintf(stderr, " --below \n"); - fprintf(stderr, " --same-as \n"); - fprintf(stderr, " --set \n"); - fprintf(stderr, " --scale x\n"); - fprintf(stderr, " --scale-from x\n"); - fprintf(stderr, " --transform ,,,,,,,,\n"); - fprintf(stderr, " --off\n"); - fprintf(stderr, " --crtc \n"); - fprintf(stderr, " --panning x[++[/x++[////]]]\n"); - fprintf(stderr, " --gamma ::\n"); - fprintf(stderr, " --primary\n"); - fprintf(stderr, " --noprimary\n"); - fprintf(stderr, " --newmode \n"); - fprintf(stderr, " \n"); - fprintf(stderr, " \n"); - fprintf(stderr, " [flags...]\n"); - fprintf(stderr, " Valid flags: +HSync -HSync +VSync -VSync\n"); - fprintf(stderr, " +CSync -CSync CSync Interlace DoubleScan\n"); - fprintf(stderr, " --rmmode \n"); - fprintf(stderr, " --addmode \n"); - fprintf(stderr, " --delmode \n"); - fprintf(stderr, " --listproviders\n"); - fprintf(stderr, " --setprovideroutputsource \n"); - fprintf(stderr, " --setprovideroffloadsink \n"); - - exit(1); - /*NOTREACHED*/ + printf("usage: %s [options]\n", program_name); + printf(" where options are:\n"); + printf(" -display or -d \n"); + printf(" --help\n"); + printf(" -o \n"); + printf(" or --orientation \n"); + printf(" -q or --query\n"); + printf(" -s /x or --size /x\n"); + printf(" -r or --rate or --refresh \n"); + printf(" -v or --version\n"); + printf(" -x (reflect in x)\n"); + printf(" -y (reflect in y)\n"); + printf(" --screen \n"); + printf(" --verbose\n"); + printf(" --current\n"); + printf(" --dryrun\n"); + printf(" --nograb\n"); + printf(" --prop or --properties\n"); + printf(" --fb x\n"); + printf(" --fbmm x\n"); + printf(" --dpi /\n"); + printf(" --output \n"); + printf(" --auto\n"); + printf(" --mode \n"); + printf(" --preferred\n"); + printf(" --pos x\n"); + printf(" --rate or --refresh \n"); + printf(" --reflect normal,x,y,xy\n"); + printf(" --rotate normal,inverted,left,right\n"); + printf(" --left-of \n"); + printf(" --right-of \n"); + printf(" --above \n"); + printf(" --below \n"); + printf(" --same-as \n"); + printf(" --set \n"); + printf(" --scale x\n"); + printf(" --scale-from x\n"); + printf(" --transform ,,,,,,,,\n"); + printf(" --off\n"); + printf(" --crtc \n"); + printf(" --panning x[++[/x++[////]]]\n"); + printf(" --gamma ::\n"); + printf(" --primary\n"); + printf(" --noprimary\n"); + printf(" --newmode \n"); + printf(" \n"); + printf(" \n"); + printf(" [flags...]\n"); + printf(" Valid flags: +HSync -HSync +VSync -VSync\n"); + printf(" +CSync -CSync CSync Interlace DoubleScan\n"); + printf(" --rmmode \n"); + printf(" --addmode \n"); + printf(" --delmode \n"); + printf(" --listproviders\n"); + printf(" --setprovideroutputsource \n"); + printf(" --setprovideroffloadsink \n"); } static void _X_NORETURN _X_ATTRIBUTE_PRINTF(1,2) @@ -180,6 +177,20 @@ warning (const char *format, ...) va_end (ap); } +static void _X_NORETURN _X_ATTRIBUTE_PRINTF(1,2) +argerr (const char *format, ...) +{ + va_list ap; + + va_start (ap, format); + fprintf (stderr, "%s: ", program_name); + vfprintf (stderr, format, ap); + fprintf (stderr, "Try '%s --help' for more information.\n", program_name); + va_end (ap); + exit (1); + /*NOTREACHED*/ +} + /* Because fmin requires C99 suppport */ static inline double dmin (double x, double y) { @@ -611,7 +622,7 @@ set_name (name_t *name, char *string, name_kind_t valid) else if (valid & name_string) set_name_string (name, string); else - usage (); + argerr ("invalid name '%s'\n", string); } static int @@ -2226,7 +2237,7 @@ check_strtol(char *s) char *endptr; int result = strtol(s, &endptr, 10); if (s == endptr) - usage(); + argerr ("failed to parse '%s' as a number\n", s); return result; } @@ -2236,7 +2247,7 @@ check_strtod(char *s) char *endptr; double result = strtod(s, &endptr); if (s == endptr) - usage(); + argerr ("failed to parse '%s' as a number\n", s); return result; } @@ -2264,7 +2275,7 @@ property_values_from_string(const char *str, const Atom type, const int format, if (token == endptr || *endptr != '\0') { - usage (); + argerr ("failed to parse '%s' as a number\n", token); } returned_bytes = realloc (returned_bytes, (nitems + 1) * bytes_per_item); @@ -2486,14 +2497,13 @@ main (int argc, char **argv) program_name = argv[0]; for (i = 1; i < argc; i++) { if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); display_name = argv[i]; continue; } - if (!strcmp("-help", argv[i])) { + if (!strcmp("-help", argv[i]) || !strcmp("--help", argv[i])) { usage(); - action_requested = True; - continue; + exit(0); } if (!strcmp ("--verbose", argv[i])) { verbose = True; @@ -2514,12 +2524,12 @@ main (int argc, char **argv) } if (!strcmp ("-s", argv[i]) || !strcmp ("--size", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%dx%d", &width, &height) == 2) { have_pixel_size = True; } else { size = check_strtol(argv[i]); - if (size < 0) usage(); + if (size < 0) argerr ("--size argument must be nonnegative\n"); } setit = True; action_requested = True; @@ -2530,7 +2540,7 @@ main (int argc, char **argv) !strcmp ("--rate", argv[i]) || !strcmp ("--refresh", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); rate = check_strtod(argv[i]); setit = True; if (output) @@ -2562,9 +2572,9 @@ main (int argc, char **argv) continue; } if (!strcmp ("--screen", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); screen = check_strtol(argv[i]); - if (screen < 0) usage(); + if (screen < 0) argerr ("--screen argument must be nonnegative\n"); continue; } if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) { @@ -2573,14 +2583,15 @@ main (int argc, char **argv) } if (!strcmp ("-o", argv[i]) || !strcmp ("--orientation", argv[i])) { char *endptr; - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); dirind = strtol(argv[i], &endptr, 10); if (argv[i] == endptr) { for (dirind = 0; dirind < 4; dirind++) { if (strcmp (direction[dirind], argv[i]) == 0) break; } } - if ((dirind < 0) || (dirind > 3)) usage(); + if ((dirind < 0) || (dirind > 3)) + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); rot = dirind; setit = True; action_requested = True; @@ -2597,7 +2608,7 @@ main (int argc, char **argv) continue; } if (!strcmp ("--output", argv[i])) { - if (++i >= argc) usage(); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output = find_output_by_name (argv[i]); if (!output) { @@ -2610,95 +2621,95 @@ main (int argc, char **argv) continue; } if (!strcmp ("--crtc", argv[i])) { - if (++i >= argc) usage(); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); set_name (&output->crtc, argv[i], name_xid|name_index); output->changes |= changes_crtc; continue; } if (!strcmp ("--mode", argv[i])) { - if (++i >= argc) usage(); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); set_name (&output->mode, argv[i], name_string|name_xid); output->changes |= changes_mode; continue; } if (!strcmp ("--preferred", argv[i])) { - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); set_name_preferred (&output->mode); output->changes |= changes_mode; continue; } if (!strcmp ("--pos", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%dx%d", &output->x, &output->y) != 2) - usage (); + argerr ("failed to parse '%s' as a position\n", argv[i]); output->changes |= changes_position; continue; } if (!strcmp ("--rotation", argv[i]) || !strcmp ("--rotate", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); for (dirind = 0; dirind < 4; dirind++) { if (strcmp (direction[dirind], argv[i]) == 0) break; } if (dirind == 4) - usage (); + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); output->rotation &= ~0xf; output->rotation |= 1 << dirind; output->changes |= changes_rotation; continue; } if (!strcmp ("--reflect", argv[i]) || !strcmp ("--reflection", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); for (dirind = 0; dirind < 4; dirind++) { if (strcmp (reflections[dirind], argv[i]) == 0) break; } if (dirind == 4) - usage (); + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); output->rotation &= ~(RR_Reflect_X|RR_Reflect_Y); output->rotation |= dirind * RR_Reflect_X; output->changes |= changes_reflection; continue; } if (!strcmp ("--left-of", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output->relation = relation_left_of; output->relative_to = argv[i]; output->changes |= changes_relation; continue; } if (!strcmp ("--right-of", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output->relation = relation_right_of; output->relative_to = argv[i]; output->changes |= changes_relation; continue; } if (!strcmp ("--above", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output->relation = relation_above; output->relative_to = argv[i]; output->changes |= changes_relation; continue; } if (!strcmp ("--below", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output->relation = relation_below; output->relative_to = argv[i]; output->changes |= changes_relation; continue; } if (!strcmp ("--same-as", argv[i])) { - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); output->relation = relation_same_as; output->relative_to = argv[i]; output->changes |= changes_relation; @@ -2706,8 +2717,8 @@ main (int argc, char **argv) } if (!strcmp ("--panning", argv[i])) { XRRPanning *pan; - if (++i>=argc) usage (); - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); pan = &output->panning; switch (sscanf (argv[i], "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d", &pan->width, &pan->height, &pan->left, &pan->top, @@ -2729,32 +2740,32 @@ main (int argc, char **argv) case 12: break; default: - usage (); + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); } output->changes |= changes_panning; continue; } if (!strcmp ("--gamma", argv[i])) { - if (!output) usage(); - if (++i>=argc) usage (); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf(argv[i], "%f:%f:%f", &output->gamma.red, &output->gamma.green, &output->gamma.blue) != 3) - usage (); + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); output->changes |= changes_gamma; setit_1_2 = True; continue; } if (!strcmp ("--brightness", argv[i])) { - if (!output) usage(); - if (++i>=argc) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf(argv[i], "%f", &output->brightness) != 1) - usage (); + argerr ("%s: invalid argument '%s'\n", argv[i-1], argv[i]); output->changes |= changes_gamma; setit_1_2 = True; continue; } if (!strcmp ("--primary", argv[i])) { - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); output->changes |= changes_primary; output->primary = True; setit_1_2 = True; @@ -2767,14 +2778,13 @@ main (int argc, char **argv) } if (!strcmp ("--set", argv[i])) { output_prop_t *prop; - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (i+2 >= argc) argerr ("%s requires two arguments\n", argv[i]); prop = malloc (sizeof (output_prop_t)); prop->next = output->props; output->props = prop; - if (++i>=argc) usage (); - prop->name = argv[i]; - if (++i>=argc) usage (); - prop->value = argv[i]; + prop->name = argv[++i]; + prop->value = argv[++i]; propit = True; output->changes |= changes_property; setit_1_2 = True; @@ -2783,10 +2793,10 @@ main (int argc, char **argv) if (!strcmp ("--scale", argv[i])) { double sx, sy; - if (!output) usage(); - if (++i>=argc) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%lfx%lf", &sx, &sy) != 2) - usage (); + argerr ("failed to parse '%s' as a scaling factor\n", argv[i]); init_transform (&output->transform); output->transform.transform.matrix[0][0] = XDoubleToFixed (sx); output->transform.transform.matrix[1][1] = XDoubleToFixed (sy); @@ -2803,12 +2813,12 @@ main (int argc, char **argv) if (!strcmp ("--scale-from", argv[i])) { int w, h; - if (!output) usage(); - if (++i>=argc) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%dx%d", &w, &h) != 2) - usage (); + argerr ("failed to parse '%s' as a scale-from size\n", argv[i]); if (w <=0 || h <= 0) - usage (); + argerr ("--scale-from dimensions must be nonnegative\n"); output->scale_from_w = w; output->scale_from_h = h; output->changes |= changes_transform; @@ -2817,8 +2827,8 @@ main (int argc, char **argv) if (!strcmp ("--transform", argv[i])) { double transform[3][3]; int k, l; - if (!output) usage(); - if (++i>=argc) usage (); + if (!output) argerr ("%s must be used after --output\n", argv[i]); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); init_transform (&output->transform); if (strcmp (argv[i], "none") != 0) { @@ -2827,7 +2837,7 @@ main (int argc, char **argv) &transform[1][0],&transform[1][1],&transform[1][2], &transform[2][0],&transform[2][1],&transform[2][2]) != 9) - usage (); + argerr ("failed to parse '%s' as a transformation\n", argv[i]); init_transform (&output->transform); for (k = 0; k < 3; k++) for (l = 0; l < 3; l++) { @@ -2841,33 +2851,33 @@ main (int argc, char **argv) continue; } if (!strcmp ("--off", argv[i])) { - if (!output) usage(); + if (!output) argerr ("%s must be used after --output\n", argv[i]); set_name_xid (&output->mode, None); set_name_xid (&output->crtc, None); output->changes |= changes_mode; continue; } if (!strcmp ("--fb", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%dx%d", &fb_width, &fb_height) != 2) - usage (); + argerr ("failed to parse '%s' as a framebuffer size\n", argv[i]); setit_1_2 = True; action_requested = True; continue; } if (!strcmp ("--fbmm", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); if (sscanf (argv[i], "%dx%d", &fb_width_mm, &fb_height_mm) != 2) - usage (); + argerr ("failed to parse '%s' as a physical size\n", argv[i]); setit_1_2 = True; action_requested = True; continue; } if (!strcmp ("--dpi", argv[i])) { char *strtod_error; - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); dpi = strtod(argv[i], &strtod_error); if (argv[i] == strtod_error) { @@ -2906,7 +2916,8 @@ main (int argc, char **argv) double clock; ++i; - if (i + 9 >= argc) usage (); + if (i + 9 >= argc) + argerr ("failed to parse '%s' as a mode specification\n", argv[i]); m->mode.name = argv[i]; m->mode.nameLength = strlen (argv[i]); i++; @@ -2945,7 +2956,7 @@ main (int argc, char **argv) { umode_t *m = malloc (sizeof (umode_t)); - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); set_name (&m->name, argv[i], name_string|name_xid); m->action = umode_destroy; m->next = umodes; @@ -2958,10 +2969,9 @@ main (int argc, char **argv) { umode_t *m = malloc (sizeof (umode_t)); - if (++i>=argc) usage (); - set_name (&m->output, argv[i], name_string|name_xid); - if (++i>=argc) usage(); - set_name (&m->name, argv[i], name_string|name_xid); + if (i+2 >= argc) argerr ("%s requires two arguments\n", argv[i]); + set_name (&m->output, argv[++i], name_string|name_xid); + set_name (&m->name, argv[++i], name_string|name_xid); m->action = umode_add; m->next = umodes; umodes = m; @@ -2973,10 +2983,9 @@ main (int argc, char **argv) { umode_t *m = malloc (sizeof (umode_t)); - if (++i>=argc) usage (); - set_name (&m->output, argv[i], name_string|name_xid); - if (++i>=argc) usage(); - set_name (&m->name, argv[i], name_string|name_xid); + if (i+2 >= argc) argerr ("%s requires two arguments\n", argv[i]); + set_name (&m->output, argv[++i], name_string|name_xid); + set_name (&m->name, argv[++i], name_string|name_xid); m->action = umode_delete; m->next = umodes; umodes = m; @@ -2992,7 +3001,7 @@ main (int argc, char **argv) } if (!strcmp("--setprovideroutputsource", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); set_name (&provider_name, argv[i], name_string|name_xid|name_index); if (++i>=argc) set_name_xid (&output_source_provider_name, 0); @@ -3004,7 +3013,7 @@ main (int argc, char **argv) } if (!strcmp("--setprovideroffloadsink", argv[i])) { - if (++i>=argc) usage (); + if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); set_name (&provider_name, argv[i], name_string|name_xid|name_index); if (++i>=argc) set_name_xid (&offload_sink_provider_name, 0); @@ -3015,7 +3024,7 @@ main (int argc, char **argv) continue; } - usage(); + argerr ("unrecognized option '%s'\n", argv[i]); } if (!action_requested) query = True; -- cgit v1.2.3 From d752d524027fbc20d9fdee06fed173e454f15370 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 6 Feb 2013 10:10:03 -0800 Subject: Bug #29603: document that there might be multiple preferred modes The X server sorts the mode list for an output with preferred modes first, and specifies how many preferred modes there are by setting the npreferred field in the XRRModeInfo structure. Update the man page to refer to preferred modes in the plural, and mention that --auto and --preferred use the *first* preferred mode. Signed-off-by: Aaron Plattner Reviewed-by: Daniel Dadap --- man/xrandr.man | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/xrandr.man b/man/xrandr.man index 2455756..900095c 100644 --- a/man/xrandr.man +++ b/man/xrandr.man @@ -78,7 +78,7 @@ screen. It can also set the screen size. If invoked without any option, it will dump the state of the outputs, showing the existing modes for each of them, with a '+' after the preferred -mode and a '*' after the current mode. +modes and a '*' after the current mode. There are a few global options. Other options modify the last output that is specified in earlier parameters in the command line. Multiple outputs may @@ -249,7 +249,7 @@ Selects an output to reconfigure. Use either the name of the output or the XID. .IP \-\-auto For connected but disabled outputs, this will enable them using their -preferred mode (or, something close to 96dpi if they have no preferred +first preferred mode (or, something close to 96dpi if they have no preferred mode). For disconnected but enabled outputs, this will disable them. .IP "\-\-mode \fImode\fP" This selects a mode. Use either the name or the XID for \fImode\fP -- cgit v1.2.3 From 7fd4f18b649f22fad4dbf9fc64b69b3e7f172207 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 6 Feb 2013 11:13:06 -0800 Subject: Bug #37043: adjust refresh rates for doublescan and interlace These two flags halve and double, respectively, the effective refresh rate of a mode. Signed-off-by: Aaron Plattner Reviewed-by: Daniel Dadap --- xrandr.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/xrandr.c b/xrandr.c index a5a9fd0..7fb0b0b 100644 --- a/xrandr.c +++ b/xrandr.c @@ -541,10 +541,22 @@ static double mode_refresh (XRRModeInfo *mode_info) { double rate; + unsigned int vTotal = mode_info->vTotal; + + if (mode_info->modeFlags & RR_DoubleScan) { + /* doublescan doubles the number of lines */ + vTotal *= 2; + } + + if (mode_info->modeFlags & RR_Interlace) { + /* interlace splits the frame into two fields */ + /* the field rate is what is typically reported by monitors */ + vTotal /= 2; + } - if (mode_info->hTotal && mode_info->vTotal) + if (mode_info->hTotal && vTotal) rate = ((double) mode_info->dotClock / - ((double) mode_info->hTotal * (double) mode_info->vTotal)); + ((double) mode_info->hTotal * (double) vTotal)); else rate = 0; return rate; -- cgit v1.2.3 From bd166184f6c1973ae2f5f99d040733db3e9e82cf Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 6 Feb 2013 14:21:57 -0800 Subject: Cast XID to unsigned int to suppress a printf warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sorry I forgot about this in commit 138b6252c0cae6599b6c8a25ffa22ffe70f227c2. That change introduced a warning: xrandr.c|645 col 5| warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘XID’ [-Wformat] Fix that by just casting the XID to unsigned int. Signed-off-by: Aaron Plattner Reviewed-by: Daniel Dadap --- xrandr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrandr.c b/xrandr.c index 7fb0b0b..adc11a6 100644 --- a/xrandr.c +++ b/xrandr.c @@ -642,7 +642,7 @@ print_name (const name_t *name) { name_kind_t kind = name->kind; - if ((kind & name_xid)) return printf("XID 0x%x", name->xid); + if ((kind & name_xid)) return printf("XID 0x%x", (unsigned int)name->xid); else if ((kind & name_string)) return printf("name %s", name->string); else if ((kind & name_index)) return printf("index %d", name->index); else return printf("unknown name"); -- cgit v1.2.3