172d277a7SGerd Hoffmann /* 272d277a7SGerd Hoffmann * QEMU EDID test tool. 372d277a7SGerd Hoffmann * 472d277a7SGerd Hoffmann * This work is licensed under the terms of the GNU GPL, version 2 or later. 572d277a7SGerd Hoffmann * See the COPYING file in the top-level directory. 672d277a7SGerd Hoffmann */ 772d277a7SGerd Hoffmann #include "qemu/osdep.h" 872d277a7SGerd Hoffmann #include "qemu/bswap.h" 972d277a7SGerd Hoffmann #include "qemu/cutils.h" 1072d277a7SGerd Hoffmann #include "hw/display/edid.h" 1172d277a7SGerd Hoffmann 12c7146542SGerd Hoffmann static qemu_edid_info info = { 13*de72c4b7SDaniel P. Berrangé .prefx = 1280, 14*de72c4b7SDaniel P. Berrangé .prefy = 800, 15fd36eadeSMarc-André Lureau }; 1672d277a7SGerd Hoffmann 1772d277a7SGerd Hoffmann static void usage(FILE *out) 1872d277a7SGerd Hoffmann { 1972d277a7SGerd Hoffmann fprintf(out, 2072d277a7SGerd Hoffmann "\n" 2172d277a7SGerd Hoffmann "This is a test tool for the qemu edid generator.\n" 2272d277a7SGerd Hoffmann "\n" 2372d277a7SGerd Hoffmann "Typically you'll pipe the output into edid-decode\n" 2472d277a7SGerd Hoffmann "to check if the generator works correctly.\n" 2572d277a7SGerd Hoffmann "\n" 2672d277a7SGerd Hoffmann "usage: qemu-edid <options>\n" 2772d277a7SGerd Hoffmann "options:\n" 2872d277a7SGerd Hoffmann " -h print this text\n" 2972d277a7SGerd Hoffmann " -o <file> set output file (stdout by default)\n" 3072d277a7SGerd Hoffmann " -v <vendor> set monitor vendor (three letters)\n" 3172d277a7SGerd Hoffmann " -n <name> set monitor name\n" 3272d277a7SGerd Hoffmann " -s <serial> set monitor serial\n" 3372d277a7SGerd Hoffmann " -d <dpi> set display resolution\n" 3472d277a7SGerd Hoffmann " -x <prefx> set preferred width\n" 3572d277a7SGerd Hoffmann " -y <prefy> set preferred height\n" 3672d277a7SGerd Hoffmann " -X <maxx> set maximum width\n" 3772d277a7SGerd Hoffmann " -Y <maxy> set maximum height\n" 3872d277a7SGerd Hoffmann "\n"); 3972d277a7SGerd Hoffmann } 4072d277a7SGerd Hoffmann 4172d277a7SGerd Hoffmann int main(int argc, char *argv[]) 4272d277a7SGerd Hoffmann { 4372d277a7SGerd Hoffmann FILE *outfile = NULL; 44bdbe824bSGerd Hoffmann uint8_t blob[512]; 45bdbe824bSGerd Hoffmann size_t size; 46fd36eadeSMarc-André Lureau uint32_t dpi = 100; 4772d277a7SGerd Hoffmann int rc; 4872d277a7SGerd Hoffmann 4972d277a7SGerd Hoffmann for (;;) { 5072d277a7SGerd Hoffmann rc = getopt(argc, argv, "ho:x:y:X:Y:d:v:n:s:"); 5172d277a7SGerd Hoffmann if (rc == -1) { 5272d277a7SGerd Hoffmann break; 5372d277a7SGerd Hoffmann } 5472d277a7SGerd Hoffmann switch (rc) { 5572d277a7SGerd Hoffmann case 'o': 5672d277a7SGerd Hoffmann if (outfile) { 5772d277a7SGerd Hoffmann fprintf(stderr, "outfile specified twice\n"); 5872d277a7SGerd Hoffmann exit(1); 5972d277a7SGerd Hoffmann } 6072d277a7SGerd Hoffmann outfile = fopen(optarg, "w"); 6172d277a7SGerd Hoffmann if (outfile == NULL) { 6272d277a7SGerd Hoffmann fprintf(stderr, "open %s: %s\n", optarg, strerror(errno)); 6372d277a7SGerd Hoffmann exit(1); 6472d277a7SGerd Hoffmann } 6572d277a7SGerd Hoffmann break; 6672d277a7SGerd Hoffmann case 'x': 6772d277a7SGerd Hoffmann if (qemu_strtoui(optarg, NULL, 10, &info.prefx) < 0) { 6872d277a7SGerd Hoffmann fprintf(stderr, "not a number: %s\n", optarg); 6972d277a7SGerd Hoffmann exit(1); 7072d277a7SGerd Hoffmann } 7172d277a7SGerd Hoffmann break; 7272d277a7SGerd Hoffmann case 'y': 7372d277a7SGerd Hoffmann if (qemu_strtoui(optarg, NULL, 10, &info.prefy) < 0) { 7472d277a7SGerd Hoffmann fprintf(stderr, "not a number: %s\n", optarg); 7572d277a7SGerd Hoffmann exit(1); 7672d277a7SGerd Hoffmann } 7772d277a7SGerd Hoffmann break; 7872d277a7SGerd Hoffmann case 'X': 7972d277a7SGerd Hoffmann if (qemu_strtoui(optarg, NULL, 10, &info.maxx) < 0) { 8072d277a7SGerd Hoffmann fprintf(stderr, "not a number: %s\n", optarg); 8172d277a7SGerd Hoffmann exit(1); 8272d277a7SGerd Hoffmann } 8372d277a7SGerd Hoffmann break; 8472d277a7SGerd Hoffmann case 'Y': 8572d277a7SGerd Hoffmann if (qemu_strtoui(optarg, NULL, 10, &info.maxy) < 0) { 8672d277a7SGerd Hoffmann fprintf(stderr, "not a number: %s\n", optarg); 8772d277a7SGerd Hoffmann exit(1); 8872d277a7SGerd Hoffmann } 8972d277a7SGerd Hoffmann break; 9072d277a7SGerd Hoffmann case 'd': 91fd36eadeSMarc-André Lureau if (qemu_strtoui(optarg, NULL, 10, &dpi) < 0) { 9272d277a7SGerd Hoffmann fprintf(stderr, "not a number: %s\n", optarg); 9372d277a7SGerd Hoffmann exit(1); 9472d277a7SGerd Hoffmann } 9572d277a7SGerd Hoffmann break; 9672d277a7SGerd Hoffmann case 'v': 9772d277a7SGerd Hoffmann info.vendor = optarg; 9872d277a7SGerd Hoffmann break; 9972d277a7SGerd Hoffmann case 'n': 10072d277a7SGerd Hoffmann info.name = optarg; 10172d277a7SGerd Hoffmann break; 10272d277a7SGerd Hoffmann case 's': 10372d277a7SGerd Hoffmann info.serial = optarg; 10472d277a7SGerd Hoffmann break; 10572d277a7SGerd Hoffmann case 'h': 10672d277a7SGerd Hoffmann usage(stdout); 10772d277a7SGerd Hoffmann exit(0); 10872d277a7SGerd Hoffmann default: 10972d277a7SGerd Hoffmann usage(stderr); 11072d277a7SGerd Hoffmann exit(1); 11172d277a7SGerd Hoffmann } 11272d277a7SGerd Hoffmann } 11372d277a7SGerd Hoffmann 11472d277a7SGerd Hoffmann if (outfile == NULL) { 11572d277a7SGerd Hoffmann outfile = stdout; 11672d277a7SGerd Hoffmann } 11772d277a7SGerd Hoffmann 118fd36eadeSMarc-André Lureau info.width_mm = qemu_edid_dpi_to_mm(dpi, info.prefx); 119fd36eadeSMarc-André Lureau info.height_mm = qemu_edid_dpi_to_mm(dpi, info.prefy); 120fd36eadeSMarc-André Lureau 12172d277a7SGerd Hoffmann memset(blob, 0, sizeof(blob)); 12272d277a7SGerd Hoffmann qemu_edid_generate(blob, sizeof(blob), &info); 123bdbe824bSGerd Hoffmann size = qemu_edid_size(blob); 124bdbe824bSGerd Hoffmann fwrite(blob, size, 1, outfile); 12572d277a7SGerd Hoffmann fflush(outfile); 12672d277a7SGerd Hoffmann 12772d277a7SGerd Hoffmann exit(0); 12872d277a7SGerd Hoffmann } 129