From 503616602234105253bfe51055c3e7c252cf87ea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 May 2013 14:39:03 +0200 Subject: [PATCH] First automated video test (running videotest and comparing results) --- ChangeLog | 4 + Makefile.util.def | 7 + grub-core/Makefile.core.def | 8 + grub-core/tests/checksums.c | 27 ++ grub-core/tests/fake_input.c | 67 ++++ grub-core/tests/lib/functional_test.c | 29 +- grub-core/tests/video_checksum.c | 435 ++++++++++++++++++++++++++ grub-core/tests/videotest_checksum.c | 286 +++++++++++++++++ grub-core/video/capture.c | 128 ++++++++ grub-core/video/video.c | 13 +- include/grub/emu/export.h | 3 +- include/grub/test.h | 9 + include/grub/video.h | 120 ++++++- tests/grub_func_test.in | 12 + tests/util/grub-shell.in | 2 + util/grub-render-label.c | 97 +----- 16 files changed, 1150 insertions(+), 97 deletions(-) create mode 100644 grub-core/tests/checksums.c create mode 100644 grub-core/tests/fake_input.c create mode 100644 grub-core/tests/video_checksum.c create mode 100644 grub-core/tests/videotest_checksum.c create mode 100644 grub-core/video/capture.c create mode 100644 tests/grub_func_test.in diff --git a/ChangeLog b/ChangeLog index b202abec7..37595a910 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-05-02 Vladimir Serbinenko + + First automated video test (running videotest and comparing results) + 2013-05-02 Vladimir Serbinenko * grub-core/commands/videotest.c: Reduce flickering and draw 6 squares diff --git a/Makefile.util.def b/Makefile.util.def index fbd37ebb6..a357341eb 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -67,6 +67,7 @@ library = { common = grub-core/video/fb/fbfill.c; common = grub-core/video/fb/video_fb.c; common = grub-core/video/video.c; + common = grub-core/video/capture.c; common = grub-core/video/colors.c; common = grub-core/unidata.c; common = grub-core/io/bufio.c; @@ -814,6 +815,12 @@ script = { common = tests/grub_script_strcmp.in; }; +script = { + testcase; + name = grub_func_test; + common = tests/grub_func_test.in; +}; + program = { testcase; name = example_unit_test; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7e19acb66..2fa0ea7be 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1731,6 +1731,9 @@ module = { name = functional_test; common = tests/lib/functional_test.c; common = tests/lib/test.c; + common = tests/video_checksum.c; + common = tests/fake_input.c; + common = video/capture.c; }; module = { @@ -1738,6 +1741,11 @@ module = { common = tests/example_functional_test.c; }; +module = { + name = videotest_checksum; + common = tests/videotest_checksum.c; +}; + module = { name = bitmap; common = video/bitmap.c; diff --git a/grub-core/tests/checksums.c b/grub-core/tests/checksums.c new file mode 100644 index 000000000..93d100fee --- /dev/null +++ b/grub-core/tests/checksums.c @@ -0,0 +1,27 @@ + { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, }, 5 }, + { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, }, 5 }, + { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgb555 */, (grub_uint32_t []) { 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgb555 */, (grub_uint32_t []) { 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgb555 */, (grub_uint32_t []) { 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 640x480xrgb565 */, (grub_uint32_t []) { 0x3c2a42f1, 0x3c2a42f1, 0x3c2a42f1, 0x3c2a42f1, 0x3c2a42f1, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 800x600xrgb565 */, (grub_uint32_t []) { 0xb25ce62a, 0xb25ce62a, 0xb25ce62a, 0xb25ce62a, 0xb25ce62a, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 1024x768xrgb565 */, (grub_uint32_t []) { 0x66cee14c, 0x66cee14c, 0x66cee14c, 0x66cee14c, 0x66cee14c, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 640x480xrgb888 */, (grub_uint32_t []) { 0x61db45b7, 0x1d867efe, 0x99613325, 0xe53c086c, 0x9543de62, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 800x600xrgb888 */, (grub_uint32_t []) { 0xa46eb37f, 0xd2a59656, 0x49f8f92d, 0x3f33dc04, 0x7aae512a, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 1024x768xrgb888 */, (grub_uint32_t []) { 0xb864a496, 0x6c22313b, 0x1505f93d, 0xc1436c90, 0xe74a6931, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgb888 */, (grub_uint32_t []) { 0x2b154617, 0x692e98df, 0xaf62fb87, 0xed59254f, 0x26164bc6, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgb888 */, (grub_uint32_t []) { 0x3b0fbc56, 0xd9d57c0e, 0xfb564a17, 0x198c8a4f, 0xbe502625, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgb888 */, (grub_uint32_t []) { 0x6e6c9b36, 0x4ae9f137, 0x27664f34, 0x3e32535, 0xfc793332, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 640x480xbgr555 */, (grub_uint32_t []) { 0x9056f776, 0x9056f776, 0x9056f776, 0x9056f776, 0x9056f776, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 800x600xbgr555 */, (grub_uint32_t []) { 0x2bde3c67, 0x2bde3c67, 0x2bde3c67, 0x2bde3c67, 0x2bde3c67, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 1024x768xbgr555 */, (grub_uint32_t []) { 0xb04615f3, 0xb04615f3, 0xb04615f3, 0xb04615f3, 0xb04615f3, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 640x480xbgr565 */, (grub_uint32_t []) { 0xba8df8dd, 0xba8df8dd, 0xba8df8dd, 0xba8df8dd, 0xba8df8dd, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 800x600xbgr565 */, (grub_uint32_t []) { 0x84ac1329, 0x84ac1329, 0x84ac1329, 0x84ac1329, 0x84ac1329, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 1024x768xbgr565 */, (grub_uint32_t []) { 0x145ad698, 0x145ad698, 0x145ad698, 0x145ad698, 0x145ad698, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 640x480xbgr888 */, (grub_uint32_t []) { 0x4af6b480, 0x923db79c, 0xfe8cc449, 0x2647c755, 0x27ee23e3, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 800x600xbgr888 */, (grub_uint32_t []) { 0x121d5e29, 0xf66c0aed, 0xdf138150, 0x3b62d594, 0x8dec962a, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 1024x768xbgr888 */, (grub_uint32_t []) { 0xae86a12c, 0x4dabbe89, 0x6d30e897, 0x8e1df732, 0x2c0644ab, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 640x480xbgr888 */, (grub_uint32_t []) { 0x2605d280, 0xc06e3172, 0xef3e6395, 0x9558067, 0xb19ec65b, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 800x600xbgr888 */, (grub_uint32_t []) { 0x9404ef3b, 0xa4fdf18, 0xad7ef98c, 0x3335c9af, 0xe6f0c255, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 1024x768xbgr888 */, (grub_uint32_t []) { 0xa008b770, 0xb98eb0d8, 0x9304b820, 0x8a82bf88, 0xc610a9d0, }, 5 }, diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c new file mode 100644 index 000000000..b514c2acc --- /dev/null +++ b/grub-core/tests/fake_input.c @@ -0,0 +1,67 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int *seq; +static int seqptr, nseq; +static struct grub_term_input *saved; + +static int +fake_getkey (struct grub_term_input *term __attribute__ ((unused))) +{ + if (seq && seqptr < nseq) + return seq[seqptr++]; + return -1; +} + +static struct grub_term_input fake_input_term = + { + .name = "fake", + .getkey = fake_getkey + }; + +void +grub_terminal_input_fake_sequence (int *seq_in, int nseq_in) +{ + if (!saved) + saved = grub_term_inputs; + if (seq) + grub_free (seq); + seq = grub_malloc (nseq_in * sizeof (seq[0])); + if (seq) + { + grub_term_inputs = &fake_input_term; + grub_memcpy (seq, seq_in, nseq_in * sizeof (seq[0])); + } + nseq = nseq_in; +} + +void +grub_terminal_input_fake_sequence_end (void) +{ + grub_term_inputs = saved; + grub_free (seq); + seq = 0; + nseq = 0; +} diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c index fd199bd63..da4d5f809 100644 --- a/grub-core/tests/lib/functional_test.c +++ b/grub-core/tests/lib/functional_test.c @@ -30,9 +30,34 @@ grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)), char **args __attribute__ ((unused))) { grub_test_t test; + int ok = 1; FOR_LIST_ELEMENTS (test, grub_test_list) - grub_test_run (test); + ok = ok && !grub_test_run (test); + if (ok) + grub_printf ("ALL TESTS PASSED\n"); + else + grub_printf ("TEST FAILURE\n"); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_test_t test; + int ok = 1; + + grub_dl_load ("exfctest"); + grub_dl_load ("videotest_checksum"); + + FOR_LIST_ELEMENTS (test, grub_test_list) + ok = ok && !grub_test_run (test); + if (ok) + grub_printf ("ALL TESTS PASSED\n"); + else + grub_printf ("TEST FAILURE\n"); return GRUB_ERR_NONE; } @@ -41,6 +66,8 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (functional_test) { cmd = grub_register_extcmd ("functional_test", grub_functional_test, 0, 0, + "Run all loaded functional tests.", 0); + cmd = grub_register_extcmd ("all_functional_test", grub_functional_all_tests, 0, 0, "Run all functional tests.", 0); } diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c new file mode 100644 index 000000000..b2aab7929 --- /dev/null +++ b/grub-core/tests/video_checksum.c @@ -0,0 +1,435 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* All tests need to include test.h for GRUB testing framework. */ +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int ctr; +static int nchk; +static char *basename; +static const grub_uint32_t *checksums; +static struct grub_video_mode_info capt_mode_info; + +#ifdef GRUB_MACHINE_EMU +#include +#include +#include +#include +#include +#include +#include +#include + +struct bmp_header +{ + grub_uint8_t magic[2]; + grub_uint32_t filesize; + grub_uint32_t reserved; + grub_uint32_t bmp_off; + grub_uint32_t head_size; + grub_uint16_t width; + grub_uint16_t height; + grub_uint16_t planes; + grub_uint16_t bpp; +} __attribute__ ((packed)); + +static void +grub_video_capture_write_bmp (const char *fname, + void *ptr, + const struct grub_video_mode_info *mode_info) +{ + int fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + struct bmp_header head; + + if (fd < 0) + { + grub_printf (_("cannot open `%s': %s"), + fname, strerror (errno)); + } + + grub_memset (&head, 0, sizeof (head)); + + head.magic[0] = 'B'; + head.magic[1] = 'M'; + + if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) + { + head.filesize = grub_cpu_to_le32 (sizeof (head) + mode_info->width * mode_info->height * 3); + head.bmp_off = grub_cpu_to_le32 (sizeof (head)); + head.bpp = grub_cpu_to_le16_compile_time (24); + } + else + { + head.filesize = grub_cpu_to_le32 (sizeof (head) + 3 * 256 + mode_info->width * mode_info->height); + head.bmp_off = grub_cpu_to_le32 (sizeof (head) + 3 * 256); + head.bpp = grub_cpu_to_le16_compile_time (8); + } + head.head_size = grub_cpu_to_le32 (sizeof (head) - 14); + head.width = grub_cpu_to_le16 (mode_info->width); + head.height = grub_cpu_to_le16 (mode_info->height); + head.planes = grub_cpu_to_le16_compile_time (1); + + head.width = grub_cpu_to_le16 (mode_info->width); + head.height = grub_cpu_to_le16 (mode_info->height); + + write (fd, &head, sizeof (head)); + + if (!(mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)) + { + struct grub_video_palette_data palette_data[256]; + int i; + int palette_len = mode_info->number_of_colors; + grub_memset (palette_data, 0, sizeof (palette_data)); + if (palette_len > 256) + palette_len = 256; + grub_video_get_palette (0, palette_len, palette_data); + for (i = 0; i < 256; i++) + { + grub_uint8_t r, g, b; + r = palette_data[i].r; + g = palette_data[i].g; + b = palette_data[i].b; + + write (fd, &b, 1); + write (fd, &g, 1); + write (fd, &r, 1); + } + } + + /* This does essentialy the same as some fbblit functions yet using + them would mean testing them against themselves so keep this + implemetation separate. */ + switch (mode_info->bytes_per_pixel) + { + case 4: + { + grub_uint8_t *buffer = xmalloc (mode_info->width * 3); + grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); + int rshift = mode_info->red_field_pos; + int gshift = mode_info->green_field_pos; + int bshift = mode_info->blue_field_pos; + int mulrshift = (8 - mode_info->red_mask_size); + int mulgshift = (8 - mode_info->green_mask_size); + int mulbshift = (8 - mode_info->blue_mask_size); + int y; + + for (y = mode_info->height - 1; y >= 0; y--) + { + grub_uint32_t *iptr = (grub_uint32_t *) ((grub_uint8_t *) ptr + mode_info->pitch * y); + int x; + grub_uint8_t *optr = buffer; + for (x = 0; x < (int) mode_info->width; x++) + { + grub_uint32_t val = *iptr++; + *optr++ = ((val >> bshift) & bmask) << mulbshift; + *optr++ = ((val >> gshift) & gmask) << mulgshift; + *optr++ = ((val >> rshift) & rmask) << mulrshift; + } + write (fd, buffer, mode_info->width * 3); + } + grub_free (buffer); + break; + } + case 3: + { + grub_uint8_t *buffer = xmalloc (mode_info->width * 3); + grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); + int rshift = mode_info->red_field_pos; + int gshift = mode_info->green_field_pos; + int bshift = mode_info->blue_field_pos; + int mulrshift = (8 - mode_info->red_mask_size); + int mulgshift = (8 - mode_info->green_mask_size); + int mulbshift = (8 - mode_info->blue_mask_size); + int y; + + for (y = mode_info->height - 1; y >= 0; y--) + { + grub_uint8_t *iptr = ((grub_uint8_t *) ptr + mode_info->pitch * y); + int x; + grub_uint8_t *optr = buffer; + for (x = 0; x < (int) mode_info->width; x++) + { + grub_uint32_t val = 0; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + val |= *iptr++ << 16; + val |= *iptr++ << 8; + val |= *iptr++; +#else + val |= *iptr++; + val |= *iptr++ << 8; + val |= *iptr++ << 16; +#endif + *optr++ = ((val >> bshift) & bmask) << mulbshift; + *optr++ = ((val >> gshift) & gmask) << mulgshift; + *optr++ = ((val >> rshift) & rmask) << mulrshift; + } + write (fd, buffer, mode_info->width * 3); + } + grub_free (buffer); + break; + } + case 2: + { + grub_uint8_t *buffer = xmalloc (mode_info->width * 3); + grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1); + int rshift = mode_info->red_field_pos; + int gshift = mode_info->green_field_pos; + int bshift = mode_info->blue_field_pos; + int mulrshift = (8 - mode_info->red_mask_size); + int mulgshift = (8 - mode_info->green_mask_size); + int mulbshift = (8 - mode_info->blue_mask_size); + int y; + + for (y = mode_info->height - 1; y >= 0; y--) + { + grub_uint16_t *iptr = (grub_uint16_t *) ((grub_uint8_t *) ptr + mode_info->pitch * y); + int x; + grub_uint8_t *optr = buffer; + for (x = 0; x < (int) mode_info->width; x++) + { + grub_uint16_t val = *iptr++; + *optr++ = ((val >> bshift) & bmask) << mulbshift; + *optr++ = ((val >> gshift) & gmask) << mulgshift; + *optr++ = ((val >> rshift) & rmask) << mulrshift; + } + write (fd, buffer, mode_info->width * 3); + } + grub_free (buffer); + break; + } + case 1: + { + int y; + + for (y = mode_info->height - 1; y >= 0; y--) + write (fd, ((grub_uint8_t *) ptr + mode_info->pitch * y), mode_info->width); + break; + } + } + close (fd); +} + +#endif + +static const char * +get_modename (void) +{ + static char buf[40]; + if (capt_mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + grub_snprintf (buf, sizeof (buf), "i%d", capt_mode_info.number_of_colors); + return buf; + } + if (capt_mode_info.red_field_pos == 0) + { + grub_snprintf (buf, sizeof (buf), "bgr%d%d%d", capt_mode_info.blue_mask_size, + capt_mode_info.green_mask_size, + capt_mode_info.red_mask_size); + return buf; + } + grub_snprintf (buf, sizeof (buf), "rgb%d%d%d", capt_mode_info.red_mask_size, + capt_mode_info.green_mask_size, + capt_mode_info.blue_mask_size); + return buf; +} + +//#define GENERATE_MODE 1 + +#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) +int genfd = -1; +#endif + +static void +checksum (void) +{ + void *ptr; + grub_uint32_t crc; + + ptr = grub_video_capture_get_framebuffer (); + + crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch * capt_mode_info.height); + if (!checksums || ctr >= nchk) + { + grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x", + basename, + capt_mode_info.width, + capt_mode_info.height, get_modename (), ctr, crc); + } + else if (crc != checksums[ctr]) + { + grub_test_assert (0, "Checksum %s_%dx%dx%s:%d failed: 0x%x vs 0x%x", + basename, + capt_mode_info.width, + capt_mode_info.height, get_modename (), + ctr, crc, checksums[ctr]); + } + else + { +#if !(defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU)) + ctr++; + return; +#endif + } +#ifdef GRUB_MACHINE_EMU + char *name = grub_xasprintf ("%s_%dx%dx%s_%d.bmp", basename, + capt_mode_info.width, + capt_mode_info.height, get_modename (), + ctr); + grub_video_capture_write_bmp (name, ptr, &capt_mode_info); +#endif + +#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) + if (genfd >= 0) + { + char buf[20]; + grub_snprintf (buf, sizeof (buf), "0x%x, ", crc); + write (genfd, buf, grub_strlen (buf)); + } +#endif + + ctr++; +} + +struct checksum_desc +{ + const char *name; + unsigned width; + unsigned height; + unsigned mode_type; + unsigned number_of_colors; + unsigned bpp; + unsigned bytes_per_pixel; + unsigned red_field_pos; + unsigned red_mask_size; + unsigned green_field_pos; + unsigned green_mask_size; + unsigned blue_field_pos; + unsigned blue_mask_size; + unsigned reserved_field_pos; + unsigned reserved_mask_size; + const grub_uint32_t *checksums; + int nchk; +}; + +const struct checksum_desc checksum_table[] = { +#include "checksums.c" +}; + +void +grub_video_checksum (const char *basename_in) +{ + unsigned i; + + grub_video_get_info (&capt_mode_info); + +#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) + if (genfd < 0) + genfd = open ("checksums.c", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (genfd >= 0) + { + char buf[400]; + + grub_snprintf (buf, sizeof (buf), "\", %d, %d, 0x%x, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d /* %dx%dx%s */, (grub_uint32_t []) { ", + capt_mode_info.width, + capt_mode_info.height, + capt_mode_info.mode_type, + capt_mode_info.number_of_colors, + capt_mode_info.bpp, + capt_mode_info.bytes_per_pixel, + capt_mode_info.red_field_pos, + capt_mode_info.red_mask_size, + capt_mode_info.green_field_pos, + capt_mode_info.green_mask_size, + capt_mode_info.blue_field_pos, + capt_mode_info.blue_mask_size, + capt_mode_info.reserved_field_pos, + capt_mode_info.reserved_mask_size, + capt_mode_info.width, + capt_mode_info.height, get_modename ()); + + write (genfd, " { \"", 5); + write (genfd, basename_in, grub_strlen (basename_in)); + write (genfd, buf, grub_strlen (buf)); + } +#endif + + basename = grub_strdup (basename_in); + nchk = 0; + checksums = 0; + /* FIXME: optimize this. */ + for (i = 0; i < ARRAY_SIZE (checksum_table); i++) + if (grub_strcmp (checksum_table[i].name, basename_in) == 0 + && capt_mode_info.width == checksum_table[i].width + && capt_mode_info.height == checksum_table[i].height + && capt_mode_info.mode_type == checksum_table[i].mode_type + && capt_mode_info.number_of_colors == checksum_table[i].number_of_colors + && capt_mode_info.bpp == checksum_table[i].bpp + && capt_mode_info.bytes_per_pixel == checksum_table[i].bytes_per_pixel + && capt_mode_info.red_field_pos == checksum_table[i].red_field_pos + && capt_mode_info.red_mask_size == checksum_table[i].red_mask_size + && capt_mode_info.green_field_pos == checksum_table[i].green_field_pos + && capt_mode_info.green_mask_size == checksum_table[i].green_mask_size + && capt_mode_info.blue_field_pos == checksum_table[i].blue_field_pos + && capt_mode_info.blue_mask_size == checksum_table[i].blue_mask_size + && capt_mode_info.reserved_field_pos == checksum_table[i].reserved_field_pos + && capt_mode_info.reserved_mask_size == checksum_table[i].reserved_mask_size) + { + nchk = checksum_table[i].nchk; + checksums = checksum_table[i].checksums; + break; + } + + ctr = 0; + grub_video_capture_refresh_cb = checksum; +} + +void +grub_video_checksum_end (void) +{ +#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) + if (genfd >= 0) + { + char buf[40]; + grub_snprintf (buf, sizeof (buf), "}, %x },\n", ctr); + write (genfd, buf, grub_strlen (buf)); + } +#endif + grub_test_assert (ctr == nchk, "Not enough checksums %s_%dx%dx%s: %d vs %d", + basename, + capt_mode_info.width, + capt_mode_info.height, get_modename (), + ctr, nchk); + grub_free (basename); + basename = 0; + nchk = 0; + checksums = 0; + ctr = 0; + grub_video_capture_refresh_cb = 0; +} diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c new file mode 100644 index 000000000..e57dae73c --- /dev/null +++ b/grub-core/tests/videotest_checksum.c @@ -0,0 +1,286 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* All tests need to include test.h for GRUB testing framework. */ +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct +{ + struct grub_video_mode_info mode_info; +} tests[] = { + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 1280, + GRUB_VIDEO_MI_RGB555 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 1600, + GRUB_VIDEO_MI_RGB555 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 2048, + GRUB_VIDEO_MI_RGB555 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 1280, + GRUB_VIDEO_MI_RGB565 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 1600, + GRUB_VIDEO_MI_RGB565 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 2048, + GRUB_VIDEO_MI_RGB565 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640 * 3, + GRUB_VIDEO_MI_RGB888 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800 * 3, + GRUB_VIDEO_MI_RGB888 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024 * 3, + GRUB_VIDEO_MI_RGB888 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640 * 4, + GRUB_VIDEO_MI_RGBA8888() + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800 * 4, + GRUB_VIDEO_MI_RGBA8888() + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024 * 4, + GRUB_VIDEO_MI_RGBA8888() + }, + }, + + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 1280, + GRUB_VIDEO_MI_BGR555 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 1600, + GRUB_VIDEO_MI_BGR555 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 2048, + GRUB_VIDEO_MI_BGR555 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 1280, + GRUB_VIDEO_MI_BGR565 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 1600, + GRUB_VIDEO_MI_BGR565 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 2048, + GRUB_VIDEO_MI_BGR565 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640 * 3, + GRUB_VIDEO_MI_BGR888 () + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800 * 3, + GRUB_VIDEO_MI_BGR888 () + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024 * 3, + GRUB_VIDEO_MI_BGR888 () + }, + }, + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640 * 4, + GRUB_VIDEO_MI_BGRA8888() + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800 * 4, + GRUB_VIDEO_MI_BGRA8888() + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024 * 4, + GRUB_VIDEO_MI_BGRA8888() + }, + }, + + }; + + +/* Functional test main method. */ +static void +videotest_checksum (void) +{ + unsigned i; + grub_font_load ("unicode"); + for (i = 0; i < ARRAY_SIZE (tests); i++) + { + grub_video_capture_start (&tests[i].mode_info, + grub_video_fbstd_colors, + GRUB_VIDEO_FBSTD_NUMCOLORS); + grub_terminal_input_fake_sequence ((int []) { '\n' }, 1); + + grub_video_checksum ("videotest"); + + char *args[] = { 0 }; + grub_command_execute ("videotest", 0, args); + grub_video_checksum_end (); + grub_video_capture_end (); + } +} + +/* Register example_test method as a functional test. */ +GRUB_FUNCTIONAL_TEST (videotest_checksum, videotest_checksum); diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c new file mode 100644 index 000000000..be7fb61af --- /dev/null +++ b/grub-core/video/capture.c @@ -0,0 +1,128 @@ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + grub_uint8_t *ptr; +} framebuffer; + +void (*grub_video_capture_refresh_cb) (void); + +static grub_err_t +grub_video_capture_swap_buffers (void) +{ + if (grub_video_capture_refresh_cb) + grub_video_capture_refresh_cb (); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_capture_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = framebuffer.render_target; + + return grub_video_fb_set_active_render_target (target); +} + +static struct grub_video_adapter grub_video_capture_adapter = + { + .name = "Render capture", + + .prio = 0, + .id = GRUB_VIDEO_ADAPTER_CAPTURE, + + .fini = grub_video_fb_fini, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = 0, + .set_palette = grub_video_fb_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_capture_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_capture_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +static struct grub_video_adapter *saved; +static struct grub_video_mode_info saved_mode_info; + +grub_err_t +grub_video_capture_start (const struct grub_video_mode_info *mode_info, + struct grub_video_palette_data *palette, + unsigned int palette_size) +{ + grub_err_t err; + grub_memset (&framebuffer, 0, sizeof (framebuffer)); + + grub_video_fb_init (); + + framebuffer.mode_info = *mode_info; + framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + + framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch); + if (!framebuffer.ptr) + return grub_errno; + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, + &framebuffer.mode_info, + framebuffer.ptr); + if (err) + return err; + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + if (err) + return err; + err = grub_video_fb_set_palette (0, palette_size, palette); + if (err) + return err; + + saved = grub_video_adapter_active; + if (saved) + { + grub_video_get_info (&saved_mode_info); + if (saved->fini) + saved->fini (); + } + grub_video_adapter_active = &grub_video_capture_adapter; + + return GRUB_ERR_NONE; +} + +void * +grub_video_capture_get_framebuffer (void) +{ + return framebuffer.ptr; +} + +void +grub_video_capture_end (void) +{ + grub_free (framebuffer.ptr); + grub_video_fb_fini (); + grub_video_adapter_active = saved; + if (saved) + { + if (saved->init) + saved->init (); + if (saved->setup) + saved->setup (saved_mode_info.width, saved_mode_info.height, 0, 0); + } +} diff --git a/grub-core/video/video.c b/grub-core/video/video.c index 844f36c08..90b525325 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -29,7 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); grub_video_adapter_t grub_video_adapter_list = NULL; /* Active video adapter. */ -static grub_video_adapter_t grub_video_adapter_active; +grub_video_adapter_t grub_video_adapter_active; /* Restore back to initial mode (where applicable). */ grub_err_t @@ -510,6 +510,9 @@ grub_video_set_mode (const char *modestring, if (! modevar) return grub_errno; + if (grub_video_adapter_active && grub_video_adapter_active->id == GRUB_VIDEO_ADAPTER_CAPTURE) + return GRUB_ERR_NONE; + if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0 || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0 || grub_memcmp (next_mode, "keep;", sizeof ("keep;") - 1) == 0) @@ -714,11 +717,3 @@ grub_video_set_mode (const char *modestring, return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no suitable video mode found")); } - -#ifdef GRUB_UTIL -void -grub_video_set_adapter (grub_video_adapter_t adapter) -{ - grub_video_adapter_active = adapter; -} -#endif diff --git a/include/grub/emu/export.h b/include/grub/emu/export.h index 1e2f0432b..7f9e4e158 100644 --- a/include/grub/emu/export.h +++ b/include/grub/emu/export.h @@ -3,4 +3,5 @@ void EXPORT_FUNC (close) (void); void EXPORT_FUNC (read) (void); void EXPORT_FUNC (write) (void); void EXPORT_FUNC (ioctl) (void); - +void EXPORT_FUNC (__errno_location) (void); +void EXPORT_FUNC (strerror) (void); diff --git a/include/grub/test.h b/include/grub/test.h index d876f5704..6aa406979 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -90,4 +90,13 @@ void grub_unit_test_fini (void); grub_test_unregister (#name); \ } +void +grub_video_checksum (const char *basename_in); +void +grub_video_checksum_end (void); +void +grub_terminal_input_fake_sequence (int *seq_in, int nseq_in); +void +grub_terminal_input_fake_sequence_end (void); + #endif /* ! GRUB_TEST_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h index bd5852e4f..630817797 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -284,7 +284,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_SIS315PRO, GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, GRUB_VIDEO_DRIVER_COREBOOT, - GRUB_VIDEO_DRIVER_IEEE1275 + GRUB_VIDEO_DRIVER_IEEE1275, + GRUB_VIDEO_ADAPTER_CAPTURE } grub_video_driver_id_t; typedef enum grub_video_adapter_prio @@ -544,9 +545,122 @@ extern void grub_video_sis315pro_fini (void); extern void grub_video_radeon_fuloong2e_fini (void); #endif -#ifdef GRUB_UTIL void grub_video_set_adapter (grub_video_adapter_t adapter); -#endif +grub_video_adapter_t +grub_video_get_adapter (void); +grub_err_t +grub_video_capture_start (const struct grub_video_mode_info *mode_info, + struct grub_video_palette_data *palette, + unsigned int palette_size); +void +grub_video_capture_end (void); + +void * +grub_video_capture_get_framebuffer (void); + +extern grub_video_adapter_t EXPORT_VAR (grub_video_adapter_active); +extern void (*grub_video_capture_refresh_cb) (void); + +#define GRUB_VIDEO_MI_RGB555(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 15, \ + x.bytes_per_pixel = 2, \ + x.number_of_colors = 256, \ + x.red_mask_size = 5, \ + x.red_field_pos = 10, \ + x.green_mask_size = 5, \ + x.green_field_pos = 5, \ + x.blue_mask_size = 5, \ + x.blue_field_pos = 0 + +#define GRUB_VIDEO_MI_RGB565(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 16, \ + x.bytes_per_pixel = 2, \ + x.number_of_colors = 256, \ + x.red_mask_size = 5, \ + x.red_field_pos = 11, \ + x.green_mask_size = 6, \ + x.green_field_pos = 5, \ + x.blue_mask_size = 5, \ + x.blue_field_pos = 0 + +#define GRUB_VIDEO_MI_RGB888(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 24, \ + x.bytes_per_pixel = 3, \ + x.number_of_colors = 256, \ + x.red_mask_size = 8, \ + x.red_field_pos = 16, \ + x.green_mask_size = 8, \ + x.green_field_pos = 8, \ + x.blue_mask_size = 8, \ + x.blue_field_pos = 0 + +#define GRUB_VIDEO_MI_RGBA8888(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 32, \ + x.bytes_per_pixel = 4, \ + x.number_of_colors = 256, \ + x.reserved_mask_size = 8, \ + x.reserved_field_pos = 24, \ + x.red_mask_size = 8, \ + x.red_field_pos = 16, \ + x.green_mask_size = 8, \ + x.green_field_pos = 8, \ + x.blue_mask_size = 8, \ + x.blue_field_pos = 0 + + +#define GRUB_VIDEO_MI_BGR555(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 15, \ + x.bytes_per_pixel = 2, \ + x.number_of_colors = 256, \ + x.red_mask_size = 5, \ + x.red_field_pos = 0, \ + x.green_mask_size = 5, \ + x.green_field_pos = 5, \ + x.blue_mask_size = 5, \ + x.blue_field_pos = 10 + +#define GRUB_VIDEO_MI_BGR565(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 16, \ + x.bytes_per_pixel = 2, \ + x.number_of_colors = 256, \ + x.red_mask_size = 5, \ + x.red_field_pos = 0, \ + x.green_mask_size = 6, \ + x.green_field_pos = 5, \ + x.blue_mask_size = 5, \ + x.blue_field_pos = 11 + +#define GRUB_VIDEO_MI_BGR888(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 24, \ + x.bytes_per_pixel = 3, \ + x.number_of_colors = 256, \ + x.red_mask_size = 8, \ + x.red_field_pos = 0, \ + x.green_mask_size = 8, \ + x.green_field_pos = 8, \ + x.blue_mask_size = 8, \ + x.blue_field_pos = 16 + +#define GRUB_VIDEO_MI_BGRA8888(x) \ + x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ + x.bpp = 32, \ + x.bytes_per_pixel = 4, \ + x.number_of_colors = 256, \ + x.reserved_mask_size = 8, \ + x.reserved_field_pos = 24, \ + x.red_mask_size = 8, \ + x.red_field_pos = 0, \ + x.green_mask_size = 8, \ + x.green_field_pos = 8, \ + x.blue_mask_size = 8, \ + x.blue_field_pos = 16 #endif /* ! GRUB_VIDEO_HEADER */ diff --git a/tests/grub_func_test.in b/tests/grub_func_test.in new file mode 100644 index 000000000..a149cf96d --- /dev/null +++ b/tests/grub_func_test.in @@ -0,0 +1,12 @@ +#! /bin/bash +set -e + +. "@builddir@/grub-core/modinfo.sh" + +out=`echo all_functional_test | @builddir@/grub-shell` + +if [ "$(echo "$out" | tail -n 1)" != "ALL TESTS PASSED" ]; then + echo "Functional test failure: $out" + exit 1 +fi + diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 1d7dfb868..dfde836d5 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -408,6 +408,8 @@ if [ x$boot = xnet ]; then timeout -s KILL $timeout "${qemu}" ${qemuopts} -nographic ${serial_null} -serial file:/dev/stdout -monitor file:/dev/null -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim elif [ x$boot = xemu ]; then grubdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" + mkdir -p "$grubdir/fonts" + cp "@builddir@/"unicode.pf2 "$grubdir/fonts/unicode.pf2" cp "${cfgfile}" "$grubdir/grub.cfg" cp "${source}" "$grubdir/testcase.cfg" @builddir@/grub-core/grub-emu -m "$device_map" -d "$grubdir" | tr -d "\r" | do_trim diff --git a/util/grub-render-label.c b/util/grub-render-label.c index 723775967..32d37746d 100644 --- a/util/grub-render-label.c +++ b/util/grub-render-label.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2012 Free Software Foundation, Inc. + * Copyright (C) 2010,2012,2013 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,6 @@ */ -#define grub_video_render_target grub_video_fbrender_target - #include #include @@ -74,58 +72,6 @@ static struct argp_option options[] = { #include #include -static struct -{ - struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; - grub_uint8_t *ptr; -} framebuffer; - -static grub_err_t -grub_video_text_render_swap_buffers (void) -{ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_text_render_set_active_render_target (struct grub_video_render_target *target) -{ - if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) - target = framebuffer.render_target; - - return grub_video_fb_set_active_render_target (target); -} - -static struct grub_video_adapter grub_video_text_render_adapter = - { - .name = "Text rendering", - - .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, - - .fini = grub_video_fb_fini, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = 0, - .set_palette = grub_video_fb_set_palette, - .get_palette = grub_video_fb_get_palette, - .set_viewport = grub_video_fb_set_viewport, - .get_viewport = grub_video_fb_get_viewport, - .map_color = grub_video_fb_map_color, - .map_rgb = grub_video_fb_map_rgb, - .map_rgba = grub_video_fb_map_rgba, - .unmap_color = grub_video_fb_unmap_color, - .fill_rect = grub_video_fb_fill_rect, - .blit_bitmap = grub_video_fb_blit_bitmap, - .blit_render_target = grub_video_fb_blit_render_target, - .scroll = grub_video_fb_scroll, - .swap_buffers = grub_video_text_render_swap_buffers, - .create_render_target = grub_video_fb_create_render_target, - .delete_render_target = grub_video_fb_delete_render_target, - .set_active_render_target = grub_video_text_render_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - static error_t argp_parser (int key, char *arg, struct argp_state *state) { @@ -208,6 +154,7 @@ main (int argc, char *argv[]) 0x77, 0x66, 0x3f, 0x27 }; int i, j, k, cptr = 0; grub_uint8_t bg, fg; + struct grub_video_mode_info mode_info; for (i = 0; i < 256; i++) ieee1275_palette[i].a = 0xff; @@ -340,32 +287,17 @@ main (int argc, char *argv[]) width = grub_font_get_string_width (font, text) + 10; height = grub_font_get_height (font); - grub_memset (&framebuffer, 0, sizeof (framebuffer)); + mode_info.width = width; + mode_info.height = height; + mode_info.pitch = width; - grub_video_fb_init (); + mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + mode_info.bpp = 8; + mode_info.bytes_per_pixel = 1; + mode_info.number_of_colors = 256; - framebuffer.mode_info.width = width; - framebuffer.mode_info.height = height; - framebuffer.mode_info.pitch = width; - - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - framebuffer.mode_info.bpp = 8; - framebuffer.mode_info.bytes_per_pixel = 1; - framebuffer.mode_info.number_of_colors = 256; - - framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - - /* For some reason sparc64 uses 32-bit pointer too. */ - framebuffer.ptr = xmalloc (height * width); - - grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, - &framebuffer.mode_info, - framebuffer.ptr); - grub_video_fb_set_active_render_target (framebuffer.render_target); - grub_video_fb_set_palette (0, ARRAY_SIZE (ieee1275_palette), - ieee1275_palette); - - grub_video_set_adapter (&grub_video_text_render_adapter); + grub_video_capture_start (&mode_info, ieee1275_palette, + ARRAY_SIZE (ieee1275_palette)); fg = grub_video_map_rgb (arguments.fgcolor.red, arguments.fgcolor.green, @@ -374,18 +306,17 @@ main (int argc, char *argv[]) arguments.bgcolor.green, arguments.bgcolor.blue); - grub_memset (framebuffer.ptr, bg, height * width); + grub_memset (grub_video_capture_get_framebuffer (), bg, height * width); grub_font_draw_string (text, font, fg, 5, grub_font_get_ascent (font)); - grub_video_set_adapter (0); - head.magic = 1; head.width = grub_cpu_to_be16 (width); head.height = grub_cpu_to_be16 (height); fwrite (&head, 1, sizeof (head), out); - fwrite (framebuffer.ptr, 1, width * height, out); + fwrite (grub_video_capture_get_framebuffer (), 1, width * height, out); + grub_video_capture_end (); if (out != stdout) fclose (out);