From 06af847b39342a46e2f456ccd708ad97fa4ffed3 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 3 Jan 2010 21:20:26 +0000 Subject: [PATCH] Add --at=X,Y flag to force cow to appear at particular location --- ChangeLog | 12 +++++++++++- src/display_cow.c | 16 ++++++++++++++-- src/xcowsay.c | 40 +++++++++++++++++++++++++++++++++++++++- xcowsay.6 | 3 +++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8995db..2f46d53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ -2010-01-04 Nick Gasson +2010-01-03 Nick Gasson + + * src/xcowsay.c (main): Add --at option to specify cow location + on screen and correspoding at_x and at_y config variables. + (parse_position_option): New function to parse options specified + as X,Y pairs. + * src/display_cow.c (display_cow): Now recognises the at_x and + at_y config variables to force cow to appear at a particular + position. + +2010-01-02 Nick Gasson * src/display_cow.c (display_cow): Fix splicing of cow across multiple monitors. Now picks a random monitor and then a random diff --git a/src/display_cow.c b/src/display_cow.c index 362b401..e3343e9 100644 --- a/src/display_cow.c +++ b/src/display_cow.c @@ -267,9 +267,21 @@ void display_cow(bool debug, const char *text, bool run_main, cowmode_t mode) if (area_h < 1) area_h = 1; + int cow_x = get_int_option("at_x"); + if (cow_x < 0) + cow_x = rand() % area_w; + else if (cow_x >= area_w) + cow_x = area_w - 1; + + int cow_y = get_int_option("at_y"); + if (cow_y < 0) + cow_y = rand() % area_h; + else if (cow_y >= area_h) + cow_y = area_h - 1; + move_shape(xcowsay.cow, - geom.x + rand()%area_w, - geom.y + bubble_off + rand()%area_h); + geom.x + cow_x, + geom.y + bubble_off + cow_y); show_shape(xcowsay.cow); xcowsay.bubble = make_shape_from_pixbuf(xcowsay.bubble_pixbuf); diff --git a/src/xcowsay.c b/src/xcowsay.c index 58dd4ca..3416b7c 100644 --- a/src/xcowsay.c +++ b/src/xcowsay.c @@ -63,6 +63,7 @@ static struct option long_options[] = { {"daemon", no_argument, &daemon_flag, 1}, {"image", required_argument, 0, 'i'}, {"monitor", required_argument, 0, 'm'}, + {"at", required_argument, 0, 'a'}, {"debug", no_argument, &debug, 1}, {0, 0, 0, 0} }; @@ -98,6 +99,7 @@ static void usage() " --cow-size=SIZE\t%s\n" " --image=FILE\t%s\n" " --monitor=N\t%s\n" + " --at=X,Y\t\t%s\n" " --debug\t\t%s\n\n" "%s\n\n" "%s\n\n" @@ -116,13 +118,14 @@ static void usage() i18n("Size of the cow (small, med, large)."), i18n("Use a different image instead of the cow."), i18n("Display cow on monitor N."), + i18n("Force the cow to appear at screen location (X,Y)."), i18n("Keep daemon attached to terminal."), i18n("Default values for these options can be specified in the " "xcowsay config\nfile. See the man page for more information."), i18n("If the display_time option is not set the display time will " "be calcuated\nfrom the reading_speed parameter multiplied by " "the word count. Set the\ndisplay time to zero to display the " - " cow indefinitely until it is clicked\non."), + "cow until it is clicked on."), i18n("Report bugs to nick@nickg.me.uk")); } @@ -153,6 +156,30 @@ static int parse_int_option(const char *optarg) } } +static void parse_position_option(const char *optarg, int *x, int *y) +{ + const char *failmsg = i18n("Error: failed to parse '%s' as position\n"); + + char *comma = strchr(optarg, ','); + if (comma == NULL) { + fprintf(stderr, failmsg, optarg); + exit(EXIT_FAILURE); + } + + char *endptr; + *x = strtol(optarg, &endptr, 10); + if (endptr != comma || endptr == optarg) { + fprintf(stderr, failmsg, optarg); + exit(EXIT_FAILURE); + } + + *y = strtol(comma + 1, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, failmsg, optarg); + exit(EXIT_FAILURE); + } +} + /* * Join all the strings in argv from ind to argc-1 into one big * string with spaces between the words. @@ -195,6 +222,8 @@ int main(int argc, char **argv) add_string_option("image_base", DEF_IMAGE_BASE); add_string_option("alt_image", DEF_ALT_IMAGE); add_int_option("monitor", -1); + add_int_option("at_x", -1); + add_int_option("at_y", -1); parse_config_file(); @@ -233,6 +262,15 @@ int main(int argc, char **argv) case 'm': set_int_option("monitor", parse_int_option(optarg)); break; + case 'a': + { + int x, y; + parse_position_option(optarg, &x, &y); + set_int_option("at_x", x); + set_int_option("at_y", y); + break; + } + break; case '?': // getopt_long already printed an error message failure = 1; diff --git a/xcowsay.6 b/xcowsay.6 index da89776..3a12a77 100644 --- a/xcowsay.6 +++ b/xcowsay.6 @@ -116,6 +116,9 @@ option is .BI "--monitor=" N Make the cow appear on monitor N. .TP +.BI "--at=" X,Y +Force that cow to appear at screen location (X,Y). +.TP .B "--debug" Print messages about what .B xcowsay -- 2.39.2