diff options
Diffstat (limited to '')
-rw-r--r-- | src/calibrator.c | 733 | ||||
-rw-r--r-- | src/calibrator.h | 108 | ||||
-rw-r--r-- | src/drmgamma.c | 283 | ||||
-rw-r--r-- | src/drmgamma.h | 182 | ||||
-rw-r--r-- | src/framebuffer.c | 215 | ||||
-rw-r--r-- | src/framebuffer.h | 154 | ||||
-rw-r--r-- | src/gamma.c | 79 | ||||
-rw-r--r-- | src/gamma.h | 52 | ||||
-rw-r--r-- | src/state.c | 172 | ||||
-rw-r--r-- | src/state.h | 89 |
10 files changed, 0 insertions, 2067 deletions
diff --git a/src/calibrator.c b/src/calibrator.c deleted file mode 100644 index a22feb4..0000000 --- a/src/calibrator.c +++ /dev/null @@ -1,733 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include "calibrator.h" - -#include "gamma.h" -#include "state.h" - -#include <unistd.h> -#include <termios.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <errno.h> - - - -/** - * Draw bars in different shades of grey, red, green and blue - * used for calibrating the contrast and brightness - */ -void draw_contrast_brightness(void) -{ - const int CONTRAST_BRIGHTNESS_LEVELS[21] = - { - 0, 17, 27, 38, 48, 59, 70, 82, 94, 106, 119, 131, - 144, 158, 171, 185, 198, 212, 226, 241, 255 - }; - size_t f; - uint32_t y, x; - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - for (y = 0; y < 4; y++) - for (x = 0; x < 21; x++) - { - int v = CONTRAST_BRIGHTNESS_LEVELS[x]; - uint32_t colour = fb_colour(v * ((y == 1) | (y == 0)), - v * ((y == 2) | (y == 0)), - v * ((y == 3) | (y == 0))); - fb_fill_rectangle(fb, colour, - x * fb->width / 21, - y * fb->height / 4, - (x + 1) * fb->width / 21 - x * fb->width / 21, - (y + 1) * fb->height / 4 - y * fb->height / 4); - } - } -} - - -/** - * Draw a seven segment display - * - * @param fb The framebuffer to draw on - * @param colour The intensity of the least intense colour to use - * @param x The X component of the top left corner of the seven segment display - * @param y The Y component of the top left corner of the seven segment display - */ -void draw_digit(framebuffer_t* restrict fb, int colour, uint32_t x, uint32_t y) -{ - uint32_t c; - - c = fb_colour(colour + 0, colour + 0, colour + 0); - fb_fill_rectangle(fb, c, x + 20, y, 80, 20); - - c = fb_colour(colour + 1, colour + 1, colour + 1); - fb_fill_rectangle(fb, c, x, y + 20, 20, 80); - - c = fb_colour(colour + 2, colour + 2, colour + 2); - fb_fill_rectangle(fb, c, x + 100, y + 20, 20, 80); - - c = fb_colour(colour + 3, colour + 3, colour + 3); - fb_fill_rectangle(fb, c, x + 20, y + 100, 80, 20); - - c = fb_colour(colour + 4, colour + 4, colour + 4); - fb_fill_rectangle(fb, c, x, y + 120, 20, 80); - - c = fb_colour(colour + 5, colour + 5, colour + 5); - fb_fill_rectangle(fb, c, x + 100, y + 120, 20, 80); - - c = fb_colour(colour + 6, colour + 6, colour + 6); - fb_fill_rectangle(fb, c, x + 20, y + 200, 80, 20); -} - - -/** - * Manipulate a CRT controllers gamma ramps to display a specific digit - * for one of the seven segment display on only that CRT controller's - * monitors - * - * @param crtc The CRT controller information - * @param colour The intensity of the least intense colour in the seven segment display - * @param value The valud of the digit to display - */ -void gamma_digit(drm_crtc_t* restrict crtc, int colour, size_t value) -{ -#define __ 0 - const int DIGITS[11] = { 1 | 2 | 4 | __ | 16 | 32 | 64, /* (0) */ - __ | __ | 4 | __ | __ | 32 | __, /* (1) */ - 1 | __ | 4 | 8 | 16 | __ | 64, /* (2) */ - 1 | __ | 4 | 8 | __ | 32 | 64, /* (3) */ - __ | 2 | 4 | 8 | __ | 32 | __, /* (4) */ - 1 | 2 | __ | 8 | __ | 32 | 64, /* (5) */ - 1 | 2 | __ | 8 | 16 | 32 | 64, /* (6) */ - 1 | __ | 4 | __ | __ | 32 | __, /* (7) */ - 1 | 2 | 4 | 8 | 16 | 32 | 64, /* (8) */ - 1 | 2 | 4 | 8 | __ | 32 | 64, /* (9) */ - __ | __ | __ | __ | __ | __ | __}; /* not visible */ - int i, digit = DIGITS[value]; - - for (i = 0; i < 7; i++) - { - uint16_t c = (digit & (1 << i)) ? 0xFFFF : 0; - int j = i + colour; - crtc->red[j] = crtc->green[j] = crtc->blue[j] = c; - } -#undef __ -} - - -/** - * Draw an unique index on each monitor - * - * @return Zero on success, -1 on error - */ -int draw_id(void) -{ - size_t f, c, id = 0; - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - fb_fill_rectangle(fb, fb_colour(0, 0, 0), 0, 0, fb->width, fb->height); - draw_digit(fb, 1, 40, 40); - draw_digit(fb, 8, 180, 40); - } - for (c = 0; c < crtc_count; c++) - { - drm_crtc_t* restrict crtc = crtcs + c; - if (drm_get_gamma(crtc) < 0) - return -1; - gamma_digit(crtc, 1, id < 10 ? 10 : (id / 10) % 10); - gamma_digit(crtc, 8, (id / 1) % 10); - id++; - if (drm_set_gamma(crtc) < 0) - return -1; - } - return 0; -} - - -/** - * Draw squares used as reference when tweeking the gamma correction - */ -void draw_gamma(void) -{ - size_t f; - uint32_t x, y; - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - for (x = 0; x < 4; x++) - { - int r = (x == 1) || (x == 0); - int g = (x == 2) || (x == 0); - int b = (x == 3) || (x == 0); - uint32_t background = fb_colour(128 * r, 128 * g, 128 * b); - uint32_t average = fb_colour(188 * r, 188 * g, 188 * b); - uint32_t high = fb_colour(255 * r, 255 * g, 255 * b); - uint32_t low = fb_colour(0, 0, 0); - uint32_t xoff = x * fb->width / 4; - fb_fill_rectangle(fb, background, xoff, 0, fb->width / 4, fb->height); - xoff += (fb->width / 4 - 200) / 2; - fb_fill_rectangle(fb, high, xoff, 40, 200, 200); - fb_fill_rectangle(fb, average, xoff + 50, 40, 100, 200); - fb_fill_rectangle(fb, average, xoff, 280, 200, 200); - for (y = 0; y < 200; y += 2) - { - fb_draw_horizontal_line(fb, high, xoff + 50, 280 + y + 0, 100); - fb_draw_horizontal_line(fb, low , xoff + 50, 280 + y + 1, 100); - } - fb_fill_rectangle(fb, average, xoff, 520, 200, 200); - fb_fill_rectangle(fb, high, xoff + 50, 520, 100, 200); - } - } -} - - -/** - * Print a pattern on the screen that can be used when - * calibrating the convergence - */ -void draw_convergence(void) -{ - uint32_t black = fb_colour(0, 0, 0); - uint32_t white = fb_colour(255, 255, 255); - uint32_t x, y; - size_t f; - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - fb_fill_rectangle(fb, black, 0, 0, fb->width, fb->height); - for (y = 0; y <= fb->height; y += 16) - { - if (y == fb->height) - y = fb->height - 1; - for (x = 0; x <= fb->width; x += 16) - { - if (x == fb->height) - x = fb->height - 1; - fb_draw_pixel(fb, white, x, y); - } - } - } -} - - -/** - * Print a pattern on the screen that can be used when - * calibrating the moiré cancellation - * - * @param gap The horizontal and vertical gap, in pixels, between the dots - * @param diagonal Whether to draw dots in a diagonal pattern - */ -void draw_moire(uint32_t gap, int diagonal) -{ - uint32_t black = fb_colour(0, 0, 0); - uint32_t white = fb_colour(255, 255, 255); - uint32_t x, y, gap2 = gap << 1; - size_t f; - gap += (uint32_t)(!diagonal); - if (diagonal) - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - fb_fill_rectangle(fb, black, 0, 0, fb->width, fb->height); - for (y = 0; y < fb->height; y += gap) - for (x = (y % gap2); x < fb->width; x += gap2) - fb_draw_pixel(fb, white, x, y); - } - else - for (f = 0; f < framebuffer_count; f++) - { - framebuffer_t* restrict fb = framebuffers + f; - fb_fill_rectangle(fb, black, 0, 0, fb->width, fb->height); - for (y = 0; y < fb->height; y += gap) - for (x = 0; x < fb->width; x += gap) - fb_draw_pixel(fb, white, x, y); - } -} - - -/** - * Analyse the monitors calibrations - * - * @return Zero on success, -1 on error - */ -int read_calibs(void) -{ - size_t c; - for (c = 0; c < crtc_count; c++) - { - if (drm_get_gamma(crtcs + c) < 0) - return -1; - - gamma_analyse(crtcs[c].gamma_stops, crtcs[c].red, gammas[0] + c, - contrasts[0] + c, brightnesses[0] + c); - gamma_analyse(crtcs[c].gamma_stops, crtcs[c].green, gammas[1] + c, - contrasts[1] + c, brightnesses[1] + c); - gamma_analyse(crtcs[c].gamma_stops, crtcs[c].blue, gammas[2] + c, - contrasts[2] + c, brightnesses[2] + c); - } - return 0; -} - - -/** - * Apply the selected calibrations to the monitors - * - * @return Zero on success, -1 on error - */ -int apply_calibs(void) -{ - size_t c; - for (c = 0; c < crtc_count; c++) - { - gamma_generate(crtcs[c].gamma_stops, crtcs[c].red, gammas[0][c], - contrasts[0][c], brightnesses[0][c]); - gamma_generate(crtcs[c].gamma_stops, crtcs[c].green, gammas[1][c], - contrasts[1][c], brightnesses[1][c]); - gamma_generate(crtcs[c].gamma_stops, crtcs[c].blue, gammas[2][c], - contrasts[2][c], brightnesses[2][c]); - - if (drm_set_gamma(crtcs + c) < 0) - return -1; - } - return 0; -} - - -/** - * Print calibrations into a file - * - * @param f The file - * @return Zero on success, -1 on error - */ -int save_calibs(FILE* f) -{ - size_t c; - for (c = 0; c < crtc_count; c++) - { - if (fprintf(f, "# index = %lu\n", - c) < 0) - return -1; - - if (fprintf(f, "edid = %s\n", - crtcs[c].edid) < 0) - return -1; - - if (fprintf(f, "brightness = %f:%f:%f\n", - brightnesses[0][c], - brightnesses[1][c], - brightnesses[2][c]) < 0) - return -1; - - if (fprintf(f, "contrast = %f:%f:%f\n", - contrasts[0][c], - contrasts[1][c], - contrasts[2][c]) < 0) - return -1; - - if (fprintf(f, "gamma = %f:%f:%f\n\n", - gammas[0][c], - gammas[1][c], - gammas[2][c]) < 0) - return -1; - } - return 0; -} - - -int main(int argc, char* argv[]) -{ - FILE* output_file = stdout; - int tty_configured = 0, rc = 0, in_fork = 0; - struct termios saved_stty; - struct termios stty; - pid_t pid; - - if ((argc > 2) || ((argc == 2) && (argv[1][0] == '-'))) - { - printf("USAGE: %s [output-file]\n", *argv); - return 0; - } - - if ((acquire_video() < 0) || - (tcgetattr(STDIN_FILENO, &saved_stty) < 0) || - (tcgetattr(STDIN_FILENO, &stty) < 0)) - goto fail; - - stty.c_lflag &= (tcflag_t)~(ICANON | ECHO); - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty) < 0) - goto fail; - tty_configured = 1; - - printf("\033[?25l"); - fflush(stdout); - - pid = fork(); - if ((pid != (pid_t)-1) && (pid != 0)) - { - int status; - retry: - if (waitpid(pid, &status, 0) != (pid_t)-1) - rc = !!status; - else - { - if (errno != EINTR) - perror(*argv); - goto retry; - } - goto done; - } - else if (pid == 0) - in_fork = 1; - - printf("\033[H\033[2J"); - printf("Please deactivate any program that dynamically\n"); - printf("applies filters to your monitors' colours\n"); - printf("and remove any existing filters.\n"); - printf("In doubt, you probably do not have any.\n"); - printf("Do not try to calibrate CRT monitors will\n"); - printf("they are cold.\n"); - printf("\n"); - printf("You will be presented with an image on each\n"); - printf("monitor. Please use the control panel on your\n"); - printf("to calibrate the contrast and brightness of\n"); - printf("each monitor. The contrasts adjusts the\n"); - printf("brightness of bright colours, and the\n"); - printf("brightness adjusts the brightness of dim\n"); - printf("colours. All rectangles are of equals size\n"); - printf("and they should be distrint from eachother.\n"); - printf("There should only be a slight difference\n"); - printf("between the two darkest colours for each\n"); - printf("colour. The grey colour does not need to\n"); - printf("be perfectly grey but should be close.\n"); - printf("The brightness should be as high as\n"); - printf("possible without the first square being\n"); - printf("any other colour than black or the two first\n"); - printf("square being too distinct from eachother. The\n"); - printf("contrast should be as high as possible without\n"); - printf("causing distortion.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - draw_contrast_brightness(); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - printf("An index will be displayed on each monitor.\n"); - printf("It behoves you to memorise them. They will\n"); - printf("be used in the output when descibing the\n"); - printf("calibrations, and is the index of the monitors\n"); - printf("that are used when changing monitor to\n"); - printf("calibrate.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - if ((read_calibs() < 0) || (draw_id() < 0)) - goto fail; - - while (getchar() != 10) - ; - - if (apply_calibs() < 0) - goto fail; - - printf("\033[H\033[2J"); - printf("You will not be given the opportunity to.\n"); - printf("calibrate your monitors' brightness and\n"); - printf("contrast using software incase your monitors\n"); - printf("could not be sufficiently calibrated using\n"); - printf("hardware.\n"); - printf("\n"); - printf("<Left> and <right> is used to change which\n"); - printf("monitor to calibrate. <Left> switches to the\n"); - printf("previous monitor (one lower in index) and\n"); - printf("<right> switches to the next monitor (one\n"); - printf("higher in index.)\n"); - printf("<Up> and <down> is used to increase and\n"); - printf("descrease the settings. respectively.\n"); - printf("<Shift+b> is used to switch to changing the.\n"); - printf("monitor's brightness and <shift+c> switches\n"); - printf("to contrast.\n"); - printf("<r> is used to switch to changing the red.\n"); - printf("channel, <g> switches to the green channel,\n"); - printf("<b> switches to the blue channel, and <a>\n"); - printf("is used to switch to change all channels.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - draw_contrast_brightness(); - - { - int c, b = 0, at_contrast = 0; - int red = 1, green = 1, blue = 1; - size_t mon = 0; - while ((c = getchar()) != 10) - { - if (b) - { - b = 0; - if ((c == 'A') && at_contrast) - { - contrasts[0][mon] += (double)red / 100; - contrasts[1][mon] += (double)green / 100; - contrasts[2][mon] += (double)blue / 100; - } - else if (c == 'A') - { - brightnesses[0][mon] += (double)red / 100; - brightnesses[1][mon] += (double)green / 100; - brightnesses[2][mon] += (double)blue / 100; - } - else if ((c == 'B') && at_contrast) - { - contrasts[0][mon] -= (double)red / 100; - contrasts[1][mon] -= (double)green / 100; - contrasts[2][mon] -= (double)blue / 100; - } - else if (c == 'B') - { - brightnesses[0][mon] -= (double)red / 100; - brightnesses[1][mon] -= (double)green / 100; - brightnesses[2][mon] -= (double)blue / 100; - } - else if (c == 'C') - mon = (mon + 1) % crtc_count; - else if (c == 'D') - mon = (mon == 0 ? crtc_count : mon) - 1; - - if ((c == 'A') || (c == 'B')) - apply_calibs(); - } - else if (c == '[') b = 1; - else if (c == 'B') at_contrast = 0; - else if (c == 'C') at_contrast = 1; - else if (c == 'r') red = 1, green = 0, blue = 0; - else if (c == 'g') red = 0, green = 1, blue = 0; - else if (c == 'b') red = 0, green = 0, blue = 1; - else if (c == 'a') red = 1, green = 1, blue = 1; - } - } - - printf("\033[H\033[2J"); - printf("You will now be presented with squares used\n"); - printf("to calibrate the gamma correction. There will\n"); - printf("be four stacks: grey, red, green and blue.\n"); - printf("Each stack has three squares: the upper square\n"); - printf("shows the characterics of how the middle square\n"); - printf("will look if the gamma is too high, and the\n"); - printf("lower shows how the middile will look if the\n"); - printf("gamma is too low. The middle square should\n"); - printf("look like it is one single colour if the gamma\n"); - printf("correction is configured correctly. You may\n"); - printf("have to look from a distance or not focus\n"); - printf("your eyes on the squares to compensate for\n"); - printf("the fact that there actually multiple colours\n"); - printf("is the square.\n"); - printf("The grey should look perfectly grey when you\n"); - printf("are done.\n"); - printf("\n"); - printf("<Left> and <right> is used to change which\n"); - printf("monitor to calibrate. <Left> switches to the\n"); - printf("previous monitor (one lower in index) and\n"); - printf("<right> switches to the next monitor (one\n"); - printf("higher in index.)\n"); - printf("<Up> and <down> is used to increase and\n"); - printf("descrease the gamma. respectively.\n"); - printf("<r> is used to switch to changing the red.\n"); - printf("channel, <g> switches to the green channel,\n"); - printf("<b> switches to the blue channel, and <a>\n"); - printf("is used to switch to change all channels.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - draw_gamma(); - - { - int c, b = 0; - int red = 1, green = 1, blue = 1; - size_t mon = 0; - while ((c = getchar()) != 10) - { - if (b) - { - b = 0; - if (c == 'A') - { - gammas[0][mon] += (double)red / 100; - gammas[1][mon] += (double)green / 100; - gammas[2][mon] += (double)blue / 100; - } - else if (c == 'B') - { - gammas[0][mon] -= (double)red / 100; - gammas[1][mon] -= (double)green / 100; - gammas[2][mon] -= (double)blue / 100; - if (gammas[0][mon] < 0) gammas[0][mon] = 0; - if (gammas[1][mon] < 0) gammas[1][mon] = 0; - if (gammas[2][mon] < 0) gammas[2][mon] = 0; - } - else if (c == 'C') - mon = (mon + 1) % crtc_count; - else if (c == 'D') - mon = (mon == 0 ? crtc_count : mon) - 1; - - if ((c == 'A') || (c == 'B')) - apply_calibs(); - } - else if (c == '[') b = 1; - else if (c == 'r') red = 1, green = 0, blue = 0; - else if (c == 'g') red = 0, green = 1, blue = 0; - else if (c == 'b') red = 0, green = 0, blue = 1; - else if (c == 'a') red = 1, green = 1, blue = 1; - } - } - - printf("\033[H\033[2J"); - printf("The next step is to calibrate the monitors'\n"); - printf("convergence settings using the monitors'\n"); - printf("control panel. White dots will be printed on the\n"); - printf("screens, you should try to get as many as\n"); - printf("possible of them to appear as pure white dots\n"); - printf("rather than dots splitted in the red, green and\n"); - printf("blue dots. On most CRT monitors this is not\n"); - printf("possible to get all corners perfect.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - draw_convergence(); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - printf("The final step is to calbirate the monitors' moiré\n"); - printf("cancellation. This too is done on the using the\n"); - printf("monitors' control panel.\n"); - printf("\n"); - printf("You can use <d> and the arrow keys to change the\n"); - printf("dot-pattern on the screens.\n"); - printf("\n"); - printf("Press ENTER to continue, and ENTER again when\n"); - printf("your are done.\n"); - fflush(stdout); - - while (getchar() != 10) - ; - - printf("\033[H\033[2J"); - fflush(stdout); - draw_moire(1, 1); - - { - int c, b = 0, d = 1; - uint32_t gap = 1; - while ((c = getchar()) != 10) - { - if (b) - { - b = 0; - if ((c == 'A') || (c == 'C')) - draw_moire(++gap, d); - else if ((c == 'B') || (c == 'D')) - { - if (--gap == 0) - gap = 1; - draw_moire(gap, d); - } - } - else if (c == '[') - b = 1; - else if (c == 'd') - draw_moire(gap, d ^= 1); - } - } - - printf("\033[H\033[2J"); - fflush(stdout); - - if (argc == 2) - { - output_file = fopen(argv[1], "w"); - if (output_file == NULL) - goto fail; - } - - if (save_calibs(output_file) < 0) - goto fail; - fflush(output_file); - - if (argc == 2) - { - if (fclose(output_file)) - goto fail; - } - - done: - if (in_fork == 0) - { - release_video(); - if (tty_configured) - tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty); - printf("\033[?25h"); - fflush(stdout); - } - return rc; - fail: - perror(*argv); - rc = 1; - goto done; -} - diff --git a/src/calibrator.h b/src/calibrator.h deleted file mode 100644 index 7b823db..0000000 --- a/src/calibrator.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef CRT_CALIBRATOR_CALIBRATOR_H -#define CRT_CALIBRATOR_CALIBRATOR_H - - -#include "framebuffer.h" -#include "drmgamma.h" - -#include <stdint.h> -#include <stddef.h> -#include <stdio.h> - - -/** - * Draw bars in different shades of grey, red, green and blue - * used for calibrating the contrast and brightness - */ -void draw_contrast_brightness(void); - -/** - * Draw a seven segment display - * - * @param fb The framebuffer to draw on - * @param colour The intensity of the least intense colour to use - * @param x The X component of the top left corner of the seven segment display - * @param y The Y component of the top left corner of the seven segment display - */ -void draw_digit(framebuffer_t* restrict fb, int colour, uint32_t x, uint32_t y); - -/** - * Manipulate a CRT controllers gamma ramps to display a specific digit - * for one of the seven segment display on only that CRT controller's - * monitors - * - * @param crtc The CRT controller information - * @param colour The intensity of the least intense colour in the seven segment display - * @param value The valud of the digit to display - */ -void gamma_digit(drm_crtc_t* restrict crtc, int colour, size_t value); - -/** - * Draw an unique index on each monitor - * - * @return Zero on success, -1 on error - */ -int draw_id(void); - -/** - * Draw squares used as reference when tweeking the gamma correction - */ -void draw_gamma(void); - -/** - * Print a pattern on the screen that can be used when - * calibrating the convergence - */ -void draw_convergence(void); - -/** - * Print a pattern on the screen that can be used when - * calibrating the moiré cancellation - * - * @param gap The horizontal and vertical gap, in pixels, between the dots - * @param diagonal Whether to draw dots in a diagonal pattern - */ -void draw_moire(uint32_t gap, int diagonal); - -/** - * Analyse the monitors calibrations - * - * @return Zero on success, -1 on error - */ -int read_calibs(void); - -/** - * Apply the selected calibrations to the monitors - * - * @return Zero on success, -1 on error - */ -int apply_calibs(void); - -/** - * Print calibrations into a file - * - * @param f The file - * @return Zero on success, -1 on error - */ -int save_calibs(FILE* f); - - -#endif - diff --git a/src/drmgamma.c b/src/drmgamma.c deleted file mode 100644 index 8f3dd97..0000000 --- a/src/drmgamma.c +++ /dev/null @@ -1,283 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include "drmgamma.h" - -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> - - - -/** - * The number of elements to allocates to a buffer for a DRM device pathname - */ -#define DRM_DEV_NAME_MAX_LEN \ - ((sizeof(DRM_DEV_NAME) + sizeof(DRM_DIR_NAME)) / sizeof(char) + 3 * sizeof(int)) - - - -/** - * Figure out how many graphics cards there are on the system - * - * @return The number of graphics cards on the system - */ -size_t drm_card_count(void) -{ - char buf[DRM_DEV_NAME_MAX_LEN]; - size_t count = 0; - - for (;; count++) - { - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, (int)count); - if (access(buf, F_OK) < 0) - return count; - } -} - -/** - * Acquire access to a graphics card - * - * @param index The index of the graphics card - * @param card Graphics card information to fill in - * @return Zero on success, -1 on error - */ -int drm_card_open(size_t index, drm_card_t* restrict card) -{ - char buf[DRM_DEV_NAME_MAX_LEN]; - int old_errno; - size_t i, n; - - card->fd = -1; - card->res = NULL; - card->connectors = NULL; - card->encoders = NULL; - card->connector_count = 0; - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, (int)index); - card->fd = open(buf, O_RDWR); - if (card->fd == -1) - goto fail; - - card->res = drmModeGetResources(card->fd); - if (card->res == NULL) - goto fail; - - card->crtc_count = (size_t)(card->res->count_crtcs); - card->connector_count = (size_t)(card->res->count_connectors); - n = card->connector_count; - - card->connectors = calloc(n, sizeof(drmModeConnector*)); - if (card->connectors == NULL) - goto fail; - card->encoders = calloc(n, sizeof(drmModeEncoder*)); - if (card->encoders == NULL) - goto fail; - - for (i = 0; i < n; i++) - { - card->connectors[i] = drmModeGetConnector(card->fd, card->res->connectors[i]); - if (card->connectors[i] == NULL) - goto fail; - - if (card->connectors[i]->encoder_id != 0) - { - card->encoders[i] = drmModeGetEncoder(card->fd, card->connectors[i]->encoder_id); - if (card->encoders[i] == NULL) - goto fail; - } - } - - return 0; - fail: - old_errno = errno; - drm_card_close(card); - errno = old_errno; - return -1; -} - - -/** - * Release access to a graphics card - * - * @param card The graphics card information - */ -void drm_card_close(drm_card_t* restrict card) -{ - size_t i, n = card->connector_count; - - if (card->encoders != NULL) - for (i = 0; i < n; i++) - if (card->encoders[i] != NULL) - drmModeFreeEncoder(card->encoders[i]); - free(card->encoders), card->encoders = NULL; - - if (card->connectors != NULL) - for (i = 0; i < n; i++) - if (card->connectors[i] != NULL) - drmModeFreeConnector(card->connectors[i]); - free(card->connectors), card->connectors = NULL; - - if (card->res != NULL) - drmModeFreeResources(card->res), card->res = NULL; - if (card->fd != -1) - close(card->fd), card->fd = -1; -} - - -/** - * Acquire access to a CRT controller - * - * @param index The index of the CRT controller - * @param card The graphics card information - * @param crtc CRT controller information to fill in - * @return Zero on success, -1 on error - */ -int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict crtc) -{ - drmModePropertyRes* restrict prop; - drmModePropertyBlobRes* restrict blob; - drmModeCrtc* restrict info; - size_t i; - int old_errno; - - crtc->edid = NULL; - crtc->red = NULL; - crtc->green = NULL; - crtc->blue = NULL; - - crtc->id = card->res->crtcs[index]; - crtc->card = card; - - crtc->connector = NULL; - crtc->encoder = NULL; - for (i = 0; i < card->connector_count; i++) - if (card->encoders[i] != NULL) - if (card->encoders[i]->crtc_id == crtc->id) - { - crtc->connector = card->connectors[i]; - crtc->encoder = card->encoders[i]; - } - - crtc->connected = (crtc->connector != NULL) && (crtc->connector->connection == DRM_MODE_CONNECTED); - - info = drmModeGetCrtc(card->fd, crtc->id); - if (info == NULL) - return -1; - crtc->gamma_stops = (size_t)(info->gamma_size); - drmModeFreeCrtc(info); - - /* `calloc` is for some reason required when reading the gamma ramps. */ - crtc->red = calloc(3 * crtc->gamma_stops, sizeof(uint16_t)); - if (crtc->red == NULL) - return -1; - crtc->green = crtc->red + crtc->gamma_stops; - crtc->blue = crtc->green + crtc->gamma_stops; - - if (crtc->connector == NULL) - return 0; - for (i = 0; i < (size_t)(crtc->connector->count_props); i++) - { - size_t j; - - prop = drmModeGetProperty(card->fd, crtc->connector->props[i]); - if (prop == NULL) - continue; - - if (strcmp(prop->name, "EDID")) - goto free_prop; - - - blob = drmModeGetPropertyBlob(card->fd, (uint32_t)(crtc->connector->prop_values[i])); - i = (size_t)(crtc->connector->count_props); - if ((blob == NULL) || (blob->data == NULL)) - goto free_blob; - - crtc->edid = malloc((blob->length * 2 + 1) * sizeof(char)); - if (crtc->edid == NULL) - { - old_errno = errno; - drmModeFreePropertyBlob(blob); - drmModeFreeProperty(prop); - free(crtc->red), crtc->red = NULL; - errno = old_errno; - return -1; - } - for (j = 0; j < blob->length; j++) - { - unsigned char c = ((unsigned char*)(blob->data))[j]; - crtc->edid[j * 2 + 0] = "0123456789ABCDEF"[(c >> 4) & 15]; - crtc->edid[j * 2 + 1] = "0123456789ABCDEF"[(c >> 0) & 15]; - } - crtc->edid[blob->length * 2] = '\0'; - - free_blob: - if (blob != NULL) - drmModeFreePropertyBlob(blob); - - free_prop: - drmModeFreeProperty(prop); - } - - return 0; -} - - -/** - * Release access to a CRT controller - * - * @param crtc The CRT controller information to fill in - */ -void drm_crtc_close(drm_crtc_t* restrict crtc) -{ - free(crtc->edid), crtc->edid = NULL; - free(crtc->red), crtc->red = NULL; -} - - -/** - * Read the gamma ramps for a CRT controller - * - * @param crtc CRT controller information - * @return Zero on success, -1 on error - */ -int drm_get_gamma(drm_crtc_t* restrict crtc) -{ - int r; - r = drmModeCrtcGetGamma(crtc->card->fd, crtc->id, (uint32_t)(crtc->gamma_stops), - crtc->red, crtc->green, crtc->blue); - return -!!r; -} - - -/** - * Apply gamma ramps for a CRT controller - * - * @param crtc CRT controller information - * @return Zero on success, -1 on error - */ -int drm_set_gamma(drm_crtc_t* restrict crtc) -{ - int r; - r = drmModeCrtcSetGamma(crtc->card->fd, crtc->id, (uint32_t)(crtc->gamma_stops), - crtc->red, crtc->green, crtc->blue); - return -!!r; -} - diff --git a/src/drmgamma.h b/src/drmgamma.h deleted file mode 100644 index e82159d..0000000 --- a/src/drmgamma.h +++ /dev/null @@ -1,182 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef CRT_CALIBRATOR_DRMGAMMA_H -#define CRT_CALIBRATOR_DRMGAMMA_H - - -#include <xf86drm.h> -#include <xf86drmMode.h> - - -/** - * Graphics card information - */ -typedef struct drm_card -{ - /** - * File descriptor for the connection to the graphics card, - * -1 if not opened - */ - int fd; - - /** - * The graphics card's mode resources, `NULL` if not acquired - */ - drmModeRes* restrict res; - - /** - * The number of CRTC:s available on the graphics card - */ - size_t crtc_count; - - /** - * The available connectors - */ - drmModeConnector** restrict connectors; - - /** - * The available encoders - */ - drmModeEncoder** restrict encoders; - - /** - * The number of connectors and encoders - */ - size_t connector_count; - -} drm_card_t; - - -/** - * CRT controller information - */ -typedef struct drm_crtc -{ - /** - * CRT controller identifier - */ - uint32_t id; - - /** - * The graphics card - */ - drm_card_t* restrict card; - - /** - * The CRT controller's connector - */ - drmModeConnector* restrict connector; - - /** - * The CRT controller's encoder - */ - drmModeEncoder* restrict encoder; - - /** - * Whether the connector is connected - */ - int connected; - - /** - * The CRT's EDID, hexadecimally encoded - */ - char* restrict edid; - - /** - * The number of stops on the gamma ramps - */ - size_t gamma_stops; - - /** - * The gamma ramp for the red channel - */ - uint16_t* restrict red; - - /** - * The gamma ramp for the green channel - */ - uint16_t* restrict green; - - /** - * The gamma ramp for the blue channel - */ - uint16_t* restrict blue; - -} drm_crtc_t; - - - -/** - * Figure out how many graphics cards there are on the system - * - * @return The number of graphics cards on the system - */ -size_t drm_card_count(void); - -/** - * Acquire access to a graphics card - * - * @param index The index of the graphics card - * @param card Graphics card information to fill in - * @return Zero on success, -1 on error - */ -int drm_card_open(size_t index, drm_card_t* restrict card); - -/** - * Release access to a graphics card - * - * @param card The graphics card information - */ -void drm_card_close(drm_card_t* restrict card); - -/** - * Acquire access to a CRT controller - * - * @param index The index of the CRT controller - * @param card The graphics card information - * @param crtc CRT controller information to fill in - * @return Zero on success, -1 on error - */ -int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict crtc); - -/** - * Release access to a CRT controller - * - * @param crtc The CRT controller information to fill in - */ -void drm_crtc_close(drm_crtc_t* restrict crtc); - -/** - * Read the gamma ramps for a CRT controller - * - * @param crtc CRT controller information - * @return Zero on success, -1 on error - */ -int drm_get_gamma(drm_crtc_t* restrict crtc); - -/** - * Apply gamma ramps for a CRT controller - * - * @param crtc CRT controller information - * @return Zero on success, -1 on error - */ -int drm_set_gamma(drm_crtc_t* restrict crtc); - - -#endif - diff --git a/src/framebuffer.c b/src/framebuffer.c deleted file mode 100644 index 55964d2..0000000 --- a/src/framebuffer.c +++ /dev/null @@ -1,215 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include "framebuffer.h" - -#include <unistd.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <stropts.h> -#include <linux/fb.h> -#include <errno.h> - - -/** - * The psuedodevice pathname pattern used to access a framebuffer - */ -#ifndef FB_DEVICE_PATTERN -# define FB_DEVICE_PATTERN "/dev/fb%lu" -#endif - - -/** - * The number of elements to allocates to a buffer for a framebuffer device pathname - */ -#define FB_DEVICE_MAX_LEN (sizeof(FB_DEVICE_PATTERN) / sizeof(char) + 3 * sizeof(size_t)) - - - -/** - * Figure out how many framebuffers there are on the system - * - * @return The number of framebuffers on the system - */ -size_t fb_count(void) -{ - char buf[FB_DEVICE_MAX_LEN]; - size_t count = 0; - - for (;; count++) - { - sprintf(buf, FB_DEVICE_PATTERN, count); - if (access(buf, F_OK) < 0) - return count; - } -} - - -/** - * Open a framebuffer - * - * @param index The index of the framebuffer to open - * @param fb Framebuffer information to fill in - * @return Zero on success, -1 on error - */ -int fb_open(size_t index, framebuffer_t* restrict fb) -{ - char buf[FB_DEVICE_MAX_LEN]; - struct fb_fix_screeninfo fix_info; - struct fb_var_screeninfo var_info; - int old_errno; - - fb->fd = -1; - fb->mem = MAP_FAILED; - - sprintf(buf, FB_DEVICE_PATTERN, index); - fb->fd = open(buf, O_RDWR); - if (fb->fd == -1) - goto fail; - - if (ioctl(fb->fd, (unsigned long int)FBIOGET_FSCREENINFO, &fix_info) || - ioctl(fb->fd, (unsigned long int)FBIOGET_VSCREENINFO, &var_info)) - goto fail; - - fb->mem = mmap(NULL, (size_t)(fix_info.smem_len), PROT_WRITE, MAP_SHARED, fb->fd, (off_t)0); - if (fb->mem == MAP_FAILED) - goto fail; - - fb->mem += var_info.xoffset * (var_info.bits_per_pixel / 8); - fb->mem += var_info.yoffset * fix_info.line_length; - - fb->width = var_info.xres; - fb->height = var_info.yres; - fb->bytes_per_pixel = var_info.bits_per_pixel / 8; - fb->line_length = fix_info.line_length; - - return 0; - fail: - old_errno = errno; - fb_close(fb); - errno = old_errno; - return -1; -} - - -/** - * Close a framebuffer - * - * @param fb The framebuffer information - */ -void fb_close(framebuffer_t* restrict fb) -{ - if (fb->fd != -1) - close(fb->fd), fb->fd = -1; -} - - -/** - * Construct an sRGB colour in 32-bit XRGB encoding to - * use when specifying colours - * - * @param red The red component from [0, 255] sRGB - * @param green The green component from [0, 255] sRGB - * @param blue The blue component from [0, 255] sRGB - * @return The colour as one 32-bit integer - */ -uint32_t fb_colour(int red, int green, int blue) -{ - uint32_t rc = 0; - rc |= (uint32_t)red, rc <<= 8; - rc |= (uint32_t)green, rc <<= 8; - rc |= (uint32_t)blue; - return rc; -} - - -/** - * Print a filled in rectangle to a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the rectangle - * @param y The starting pixel on the Y axis for the rectangle - * @param width The width of the rectangle, in pixels - * @param height The height of the rectangle, in pixels - */ -void fb_fill_rectangle(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t width, uint32_t height) -{ - int8_t* mem = fb->mem + y * fb->line_length; - size_t x1 = x * fb->bytes_per_pixel; - size_t x2 = (x + width) * fb->bytes_per_pixel; - size_t y2 = y + height; - size_t x_, y_; - - for (y_ = y; y_ != y2; y_++, mem += fb->line_length) - for (x_ = x1; x_ != x2; x_ += fb->bytes_per_pixel) - { - int8_t* pixel = mem + x_; - *(uint32_t*)pixel = colour; - } -} - - -/** - * Draw a horizontal line segment on a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the line segment - * @param y The starting pixel on the Y axis for the line segment - * @param length The length of the line segment, in pixels - */ -void fb_draw_horizontal_line(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t length) -{ - int8_t* mem = fb->mem + y * fb->line_length; - size_t x1 = x * fb->bytes_per_pixel; - size_t x2 = (x + length) * fb->bytes_per_pixel; - size_t x_; - - for (x_ = x1; x_ != x2; x_ += fb->bytes_per_pixel) - { - int8_t* pixel = mem + x_; - *(uint32_t*)pixel = colour; - } -} - - -/** - * Draw a vertical line segment on a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the line segment - * @param y The starting pixel on the Y axis for the line segment - * @param length The length of the line segment, in pixels - */ -void fb_draw_vertical_line(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t length) -{ - int8_t* mem = fb->mem + y * fb->line_length + x * fb->bytes_per_pixel; - size_t y2 = y + length; - size_t y_; - - for (y_ = y; y_ != y2; y_++, mem += fb->line_length) - *(uint32_t*)mem = colour; -} - diff --git a/src/framebuffer.h b/src/framebuffer.h deleted file mode 100644 index 11102ff..0000000 --- a/src/framebuffer.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef CRT_CALIBRATOR_FRAMEBUFFER_H -#define CRT_CALIBRATOR_FRAMEBUFFER_H - - -#include <stddef.h> -#include <stdint.h> - - -/** - * Framebuffer information - */ -typedef struct framebuffer -{ - /** - * The file descriptor used to access the framebuffer, -1 if not opened - */ - int fd; - - /** - * The width of the display in pixels - */ - uint32_t width; - - /** - * The height of the display in pixels - */ - uint32_t height; - - /** - * Increment for `mem` to move to next pixel on the line - */ - uint32_t bytes_per_pixel; - - /** - * Increment for `mem` to move down one line but stay in the same column - */ - uint32_t line_length; - - /** - * Framebuffer pointer, `MAP_FAILED` (from <sys/mman.h>) if not mapped - */ - int8_t* mem; - -} framebuffer_t; - - -/** - * Figure out how many framebuffers there are on the system - * - * @return The number of framebuffers on the system - */ -size_t fb_count(void); - -/** - * Open a framebuffer - * - * @param index The index of the framebuffer to open - * @param fb Framebuffer information to fill in - * @return Zero on success, -1 on error - */ -int fb_open(size_t index, framebuffer_t* restrict fb); - -/** - * Close a framebuffer - * - * @param fb The framebuffer information - */ -void fb_close(framebuffer_t* restrict fb); - -/** - * Construct an sRGB colour in 32-bit XRGB encoding to - * use when specifying colours - * - * @param red The red component from [0, 255] sRGB - * @param green The green component from [0, 255] sRGB - * @param blue The blue component from [0, 255] sRGB - * @return The colour as one 32-bit integer - */ -uint32_t fb_colour(int red, int green, int blue) __attribute__((const)); - -/** - * Print a filled in rectangle to a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the rectangle - * @param y The starting pixel on the Y axis for the rectangle - * @param width The width of the rectangle, in pixels - * @param height The height of the rectangle, in pixels - */ -void fb_fill_rectangle(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t width, uint32_t height); - -/** - * Draw a horizontal line segment on a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the line segment - * @param y The starting pixel on the Y axis for the line segment - * @param length The length of the line segment, in pixels - */ -void fb_draw_horizontal_line(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t length); - -/** - * Draw a vertical line segment on a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The starting pixel on the X axis for the line segment - * @param y The starting pixel on the Y axis for the line segment - * @param length The length of the line segment, in pixels - */ -void fb_draw_vertical_line(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y, uint32_t length); - - -/** - * Draw a single on a framebuffer - * - * @param fb The framebuffer - * @param colour The colour to use when drawing the rectangle - * @param x The pixel's position on the X axis - * @param y The pixel's position on the Y axis - */ -static inline void fb_draw_pixel(framebuffer_t* restrict fb, uint32_t colour, - uint32_t x, uint32_t y) -{ - int8_t* mem = fb->mem + y * fb->line_length + x * fb->bytes_per_pixel; - *(uint32_t*)mem = colour; -} - - - -#endif - diff --git a/src/gamma.c b/src/gamma.c deleted file mode 100644 index 79a50f7..0000000 --- a/src/gamma.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include "gamma.h" - -#include <math.h> - - -/** - * Analyse a gamma ramp - * - * @param stops The number of stops in the gamma ramp - * @param ramp The gamma ramp - * @param gamma Output parameter for the gamma - * @param contrast Output parameter for the contrast - * @param brightness Output parameter for the brightness - */ -void gamma_analyse(size_t stops, const uint16_t* restrict ramp, double* restrict gamma, - double* restrict contrast, double* restrict brightness) -{ - double min, middle, max; - *brightness = min = (double)(ramp[0]) / (double)0xFFFF; - *contrast = max = (double)(ramp[stops - 1]) / (double)0xFFFF; - middle = (double)(ramp[stops / 2]) / (double)0xFFFF; - - if (stops % 2 == 0) - { - middle += (double)(ramp[stops / 2 - 1]) / (double)0xFFFF; - middle /= (double)2; - } - - middle = (middle - min) / (max - min); - *gamma = -log((double)2) / log(middle); -} - - -/** - * Generate a gamma ramp - * - * @param stops The number of stops in the gamma ramp - * @param ramp Memory area to where to write the gamma ramp - * @param gamma The gamma - * @param contrast The contrast - * @param brightness The brightness - */ -void gamma_generate(size_t stops, uint16_t* restrict ramp, double gamma, - double contrast, double brightness) -{ - double diff = contrast - brightness; - double gamma_ = (double)1 / gamma; - size_t i; - int32_t y; - double y_; - - for (i = 0; i < stops; i++) - { - y_ = (double)i / (double)stops; - y_ = pow(y_, gamma_) * diff + brightness; - y = (int32_t)(y_ * 0xFFFF); - if (y < 0x0000) y = 0x0000; - if (y > 0xFFFF) y = 0xFFFF; - ramp[i] = (uint16_t)y; - } -} - diff --git a/src/gamma.h b/src/gamma.h deleted file mode 100644 index 9652598..0000000 --- a/src/gamma.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef CRT_CALIBRATOR_GAMMA_H -#define CRT_CALIBRATOR_GAMMA_H - - -#include <stddef.h> -#include <stdint.h> - - -/** - * Analyse a gamma ramp - * - * @param stops The number of stops in the gamma ramp - * @param ramp The gamma ramp - * @param gamma Output parameter for the gamma - * @param contrast Output parameter for the contrast - * @param brightness Output parameter for the brightness - */ -void gamma_analyse(size_t stops, const uint16_t* restrict ramp, double* restrict gamma, - double* restrict contrast, double* restrict brightness); - -/** - * Generate a gamma ramp - * - * @param stops The number of stops in the gamma ramp - * @param ramp Memory area to where to write the gamma ramp - * @param gamma The gamma - * @param contrast The contrast - * @param brightness The brightness - */ -void gamma_generate(size_t stops, uint16_t* restrict ramp, double gamma, - double contrast, double brightness); - - -#endif - diff --git a/src/state.c b/src/state.c deleted file mode 100644 index b4ec11a..0000000 --- a/src/state.c +++ /dev/null @@ -1,172 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include "state.h" - -#include <stdlib.h> - - -/** - * The framebuffers on the system - */ -framebuffer_t* restrict framebuffers = NULL; - -/** - * The number of elements in `framebuffers` - */ -size_t framebuffer_count = 0; - -/** - * The graphics cards on the system - */ -drm_card_t* restrict cards = NULL; - -/** - * The number of elements in `cards` - */ -size_t card_count = 0; - -/** - * The connected CRT controllers on the system - */ -drm_crtc_t* restrict crtcs = NULL; - -/** - * The software brightness setting on each connected CRT controller, on each channel - */ -double* restrict brightnesses[3]; - -/** - * The software contrast setting on each connected CRT controller, on each channel - */ -double* restrict contrasts[3]; - -/** - * The gamma correction on each connected CRT controller, on each channel - */ -double* restrict gammas[3]; - -/** - * The number of elements in `crtcs`, `brightnesses[]`, `contrasts[]` and `gammas[]` - */ -size_t crtc_count = 0; - - - -/** - * Acquire video control - * - * @return Zero on success, -1 on error - */ -int acquire_video(void) -{ - size_t f, c, i, fn = fb_count(), cn = drm_card_count(); - drm_crtc_t* restrict old_crtcs; - - framebuffers = malloc(fn * sizeof(framebuffer_t)); - if (framebuffers == NULL) - return -1; - - for (f = 0; f < fn; f++) - { - framebuffer_t fb; - if (fb_open(f, &fb) < 0) - return -1; - framebuffers[framebuffer_count++] = fb; - } - - cards = malloc(cn * sizeof(drm_card_t)); - if (cards == NULL) - return -1; - - for (c = 0; c < cn; c++) - { - drm_card_t card; - if (drm_card_open(c, &card) < 0) - return -1; - cards[card_count++] = card; - - old_crtcs = crtcs; - crtcs = realloc(crtcs, (crtc_count + card.crtc_count) * sizeof(drm_crtc_t)); - if (crtcs == NULL) - { - crtcs = old_crtcs; - return -1; - } - - for (i = 0; i < card.crtc_count; i++) - { - drm_crtc_t crtc; - if (drm_crtc_open(i, cards + c, &crtc) < 0) - return -1; - if (crtc.connected) - crtcs[crtc_count++] = crtc; - else - drm_crtc_close(&crtc); - } - } - - for (c = 0; c < 3; c++) - { - brightnesses[c] = malloc(crtc_count * sizeof(double)); - if (brightnesses[c] == NULL) - return -1; - - contrasts[c] = malloc(crtc_count * sizeof(double)); - if (contrasts[c] == NULL) - return -1; - - gammas[c] = malloc(crtc_count * sizeof(double)); - if (gammas[c] == NULL) - return -1; - } - - return 0; -} - - -/** - * Release video control - */ -void release_video(void) -{ - size_t i; - - for (i = 0; i < crtc_count; i++) - drm_crtc_close(crtcs + i); - crtc_count = 0; - - for (i = 0; i < card_count; i++) - drm_card_close(cards + i); - card_count = 0; - - for (i = 0; i < framebuffer_count; i++) - fb_close(framebuffers + i); - framebuffer_count = 0; - - for (i = 0; i < 3; i++) - { - free(brightnesses[i]), brightnesses[i] = NULL; - free(contrasts[i]), contrasts[i] = NULL; - free(gammas[i]), gammas[i] = NULL; - } - - free(crtcs), crtcs = NULL; - free(cards), cards = NULL; - free(framebuffers), framebuffers = NULL; -} - diff --git a/src/state.h b/src/state.h deleted file mode 100644 index da4a580..0000000 --- a/src/state.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * crt-calibrator – Calibration utility for CRT monitors - * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef CRT_CALIBRATOR_STATE_H -#define CRT_CALIBRATOR_STATE_H - - -#include "framebuffer.h" -#include "drmgamma.h" - -#include <stddef.h> - - -/** - * The framebuffers on the system - */ -extern framebuffer_t* restrict framebuffers; - -/** - * The number of elements in `framebuffers` - */ -extern size_t framebuffer_count; - -/** - * The graphics cards on the system - */ -extern drm_card_t* restrict cards; - -/** - * The number of elements in `cards` - */ -extern size_t card_count; - -/** - * The connected CRT controllers on the system - */ -extern drm_crtc_t* restrict crtcs; - -/** - * The software brightness setting on each connected CRT controller, on each channel - */ -extern double* restrict brightnesses[3]; - -/** - * The software contrast setting on each connected CRT controller, on each channel - */ -extern double* restrict contrasts[3]; - -/** - * The gamma correction on each connected CRT controller, on each channel - */ -extern double* restrict gammas[3]; - -/** - * The number of elements in `crtcs`, `brightnesses[]`, `contrasts[]` and `gammas[]` - */ -extern size_t crtc_count; - - - -/** - * Acquire video control - * - * @return Zero on success, -1 on error - */ -int acquire_video(void); - -/** - * Release video control - */ -void release_video(void); - - -#endif - |