/* * Copyright (c) 2019 Clementine Computing LLC. * * This file is part of PopuFare. * * PopuFare is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PopuFare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PopuFare. If not, see . * */ #include #include #include #include #include #include "fbutil.h" void usage(char *progname) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s [-x nnn] [-y nnn] [-f 0|1|2] [-o] [[-m] \"message to display\"]\n", progname); fprintf(stderr, "\n"); fprintf(stderr, "\t-x nnn\t Specifies the X coordinate to start drawing the message at.\n\t \t(Defaults to centered if none is specified).\n"); fprintf(stderr, "\t-y nnn\t Specifies the Y coordinate to start drawing the message at.\n\t \t(Defaults to centered if none is specified).\n"); fprintf(stderr, "\t-f n \t Specifies the font to draw the message with.\n\t \t(Defaults to 2 [0 = tiny, 1 = medium, 2 = large]).\n"); fprintf(stderr, "\t-o \t Specifies that we want to draw the message over the current screen without clearing.\n"); fprintf(stderr, "\t-m msg\t Specifies that the next parameter is the message, even if it starts with a '-'.\n"); fprintf(stderr, "\t-b \t Specifies that we want the text to pop up in a translucent box all fancy like.\n"); fprintf(stderr, "Any arguments after the message are ignored. If no message is specified, a blank message is displayed.\n\n"); exit(1); } int x = 0, y = 0, width = 0, height = 0; int font = 2; char *str = NULL; int flag_bits = 0; enum { FLAG_X = 0, FLAG_Y, FLAG_F, FLAG_O, FLAG_MSG, FLAG_BOX, NUM_FLAGS }; #define FLAG_BIT(x) (1 << (x)) #define ADD_FLAG(x) (flag_bits |= FLAG_BIT(x)) #define CLEAR_FLAG(x) (flag_bits &= ~FLAG_BIT(x)) #define TEST_FLAG(x) (flag_bits & FLAG_BIT(x) ) char flag_chars[NUM_FLAGS] = {'x', 'y', 'f', 'o' , 'm', 'b'}; //What character following a - constitutes this flag char flag_param_types[NUM_FLAGS] = {'i', 'i', 'i', '\0', 's', '\0'}; //What parameter type does this flag take: //i = (int) s = (char *) void *flag_vars[NUM_FLAGS] = {&x, &y, &font, NULL, &str, NULL}; //Okay, now for an array of pointers as spec'd above. NULL means no param. void parse_command_line(int argc, char **argv) { int i, j; for(i = 1; i < argc; i++) { if(argv[i][0] != '-') { if(TEST_FLAG(FLAG_MSG)) { break; } str = argv[i]; i++; break; } else { for(j = 0; j < NUM_FLAGS; j++) //For all the flags we have... { if(argv[i][1] == flag_chars[j]) //If the current argument (i) matches the current flag (j) { if(TEST_FLAG(j)) //See if we already've got one... { fprintf(stderr, "-%c specified more than once!\n", flag_chars[j]); usage(argv[0]); exit(1); } ADD_FLAG(j); //Mark us as having this flag (j) //Make sure we are expecting a parameter if(flag_vars[j] != NULL) { if( (i + 1) >= argc ) { fprintf(stderr, "Flag -%c expects a parameter, but none was specified!\n", flag_chars[j]); usage(argv[0]); exit(1); } else { i++; } switch(flag_param_types[j]) { case 'i': //for an integer, convert it if((argv[i][0] < '0') || (argv[i][0] > '9')) { fprintf(stderr, "Flag -%c expects a numeric argument but got \"%s\" instead!\n", flag_chars[j], argv[i]); usage(argv[0]); exit(1); break; } *((int *)flag_vars[j]) = (int)strtol(argv[i], NULL, 10); break; case 's': //for a string, assign the string pointer of our argv[i] to *param such that *((char **)flag_vars[j]) = argv[i]; //**flag_vars[j] points to the same string as argv[i] break; default: fprintf(stderr, "Flag -%c expects a parameter of unknown type!\n", flag_chars[j]); usage(argv[0]); exit(1); break; } //switch param type } //if flag takes param break; } //if flag match } //loop through out flag list (for j) if(j == NUM_FLAGS) { fprintf(stderr, "Unknown flag: \"%s\"!\n", argv[i]); usage(argv[0]); exit(1); } } //else (we are not processing a non-flag) } //loop though arguments (for i) if(str == NULL) { fprintf(stderr, "No message specified, using blank message \"\"\n"); str = ""; } if(i < argc) { fprintf(stderr, "Warning: Ignored the last %d parameters:", argc - i); for(j = i; j < argc; j++) { fprintf(stderr, " \"%s\"", argv[j]); } fprintf(stderr, "\n"); } } int main(int argc, char **argv) { parse_command_line(argc, argv); if(open_framebuffer_nondestructive()) { fprintf(stderr,"Cannot open framebuffer!\n"); } set_font(font); font_cell_size(&width, &height); width *= strlen(str); if(!TEST_FLAG(FLAG_X)) { x = (XRES - width) / 2; } if(!TEST_FLAG(FLAG_Y)) { y = (YRES - height) / 2; } if(!TEST_FLAG(FLAG_O)) { set_color(255,255,255); cls(); } if(TEST_FLAG(FLAG_BOX)) { //Shadow set_rawcolor(FBCOLOR_TRANSLUCENT | FBCOLOR_DKGRAY); set_pos(x - 8, y - 8); box_fill(x + width + 24, y + height + 24); //Dialog Body set_rawcolor(FBCOLOR_LTCYAN); set_pos(x - 16, y - 16); box_fill(x + width + 16, y + height + 16); //Dialog Outline set_rawcolor(FBCOLOR_BLACK); set_pos(x - 16, y - 16); box(x + width + 16, y + height + 16); } set_color(0,0,0); set_pos(x,y); print_string(str, 0); present_framebuffer(); close_framebuffer(); return 0; }