diff options
-rw-r--r-- | src/calibrator.c | 136 | ||||
-rw-r--r-- | src/calibrator.h | 19 | ||||
-rw-r--r-- | src/drmgamma.c | 8 | ||||
-rw-r--r-- | src/framebuffer.c | 12 | ||||
-rw-r--r-- | src/framebuffer.h | 2 | ||||
-rw-r--r-- | src/gamma.c | 6 | ||||
-rw-r--r-- | src/state.c | 135 | ||||
-rw-r--r-- | src/state.h | 74 |
8 files changed, 283 insertions, 109 deletions
diff --git a/src/calibrator.c b/src/calibrator.c index 38987d3..4f50537 100644 --- a/src/calibrator.c +++ b/src/calibrator.c @@ -18,6 +18,7 @@ #include "calibrator.h" #include "gamma.h" +#include "state.h" #include <stdio.h> @@ -26,22 +27,19 @@ /** * Draw bars in different shades of grey, red, green and blue * used for calibrating the contrast and brightness - * - * @return Zero on success, -1 on error */ -int draw_contrast_brightness(void) +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, y, x, fn = fb_count(); - for (f = 0; f < fn; f++) + size_t f; + uint32_t y, x; + for (f = 0; f < framebuffer_count; f++) { - framebuffer_t fb; - if (fb_open(f, &fb) < 0) - return -1; + framebuffer_t* restrict fb = framebuffers + f; for (y = 0; y < 4; y++) for (x = 0; x < 21; x++) { @@ -49,15 +47,13 @@ int draw_contrast_brightness(void) 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); + 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); } - fb_close(&fb); } - return 0; } @@ -101,12 +97,11 @@ void draw_digit(framebuffer_t* restrict fb, int colour, uint32_t x, uint32_t y) * 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 - * @return Zero on success, -1 on error + * @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 */ -int gamma_digit(drm_crtc_t* restrict crtc, int colour, size_t value) +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) */ @@ -124,9 +119,9 @@ int gamma_digit(drm_crtc_t* restrict crtc, int colour, size_t value) for (i = 0; i < 7; i++) { - uint16_t value = (digit & (1 << i)) ? 0xFFFF : 0; + uint16_t c = (digit & (1 << i)) ? 0xFFFF : 0; int j = i + colour; - crtc->red[j] = crtc->green[j] = crtc->blue[j] = value; + crtc->red[j] = crtc->green[j] = crtc->blue[j] = c; } #undef __ } @@ -135,53 +130,28 @@ int 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 + * @return Zero on success, -1 on error */ int draw_id(void) { - size_t f, c, i, id = 0, fn = fb_count(), cn = drm_card_count(); - for (f = 0; f < fn; f++) + size_t f, c, id = 0; + for (f = 0; f < framebuffer_count; f++) { - framebuffer_t fb; - if (fb_open(f, &fb) < 0) - return -1; - 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); - fb_close(&fb); + 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 < cn; c++) + for (c = 0; c < crtc_count; c++) { - drm_card_t card; - if (drm_card_open(c, &card) < 0) + 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; - for (i = 0; i < card.crtc_count; i++) - { - drm_crtc_t crtc; - if (drm_crtc_open(i, &card, &crtc) < 0) - { - drm_card_close(&card); - return -1; - } - if (crtc.connected == 0) - goto not_connected; - if (drm_get_gamma(&crtc) < 0) - goto crtc_fail; - gamma_digit(&crtc, 1, id < 10 ? 10 : (id / 10) % 10); - gamma_digit(&crtc, 8, (id / 1) % 10); - id++; - if (drm_set_gamma(&crtc) < 0) - goto crtc_fail; - not_connected: - drm_crtc_close(&crtc); - - continue; - crtc_fail: - drm_crtc_close(&crtc); - drm_card_close(&card); - return -1; - } - drm_card_close(&card); } return 0; } @@ -189,17 +159,14 @@ int draw_id(void) /** * Draw squares used as reference when tweeking the gamma correction - * - * @return Zero on success, -1 on error */ -int draw_gamma(void) +void draw_gamma(void) { - size_t f, x, y, fn = fb_count(); - for (f = 0; f < fn; f++) + size_t f; + uint32_t x, y; + for (f = 0; f < framebuffer_count; f++) { - framebuffer_t fb; - if (fb_open(f, &fb) < 0) - return -1; + framebuffer_t* restrict fb = framebuffers + f; for (x = 0; x < 4; x++) { int r = (x == 1) || (x == 0); @@ -209,34 +176,37 @@ int draw_gamma(void) 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); + 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_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); + fb_fill_rectangle(fb, average, xoff, 520, 200, 200); + fb_fill_rectangle(fb, high, xoff + 50, 520, 100, 200); } - fb_close(&fb); } - return 0; } int main(int argc __attribute__((unused)), char* argv[]) { - if (draw_gamma() < 0) + if (acquire_video() < 0) + goto fail; + + if (draw_id() < 0) goto fail; + release_video(); return 0; fail: perror(*argv); + release_video(); return 1; } diff --git a/src/calibrator.h b/src/calibrator.h index d953efd..7fed267 100644 --- a/src/calibrator.h +++ b/src/calibrator.h @@ -29,10 +29,8 @@ /** * Draw bars in different shades of grey, red, green and blue * used for calibrating the contrast and brightness - * - * @return Zero on success, -1 on error */ -int draw_contrast_brightness(void); +void draw_contrast_brightness(void); /** * Draw a seven segment display @@ -49,26 +47,23 @@ void draw_digit(framebuffer_t* restrict fb, int colour, uint32_t x, uint32_t y); * 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 - * @return Zero on success, -1 on error + * @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 */ -int gamma_digit(drm_crtc_t* restrict crtc, int colour, size_t value); +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 + * @return Zero on success, -1 on error */ int draw_id(void); /** * Draw squares used as reference when tweeking the gamma correction - * - * @return Zero on success, -1 on error */ -int draw_gamma(void); +void draw_gamma(void); #endif diff --git a/src/drmgamma.c b/src/drmgamma.c index e0dcbfb..d7e04dc 100644 --- a/src/drmgamma.c +++ b/src/drmgamma.c @@ -197,7 +197,7 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict crtc->green = crtc->red + crtc->gamma_stops; crtc->blue = crtc->green + crtc->gamma_stops; - for (i = 0; i < crtc->connector->count_props; i++) + for (i = 0; i < (size_t)(crtc->connector->count_props); i++) { size_t j; @@ -210,7 +210,7 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict blob = drmModeGetPropertyBlob(card->fd, (uint32_t)(crtc->connector->prop_values[i])); - i = crtc->connector->count_props; + i = (size_t)(crtc->connector->count_props); if ((blob == NULL) || (blob->data == NULL)) goto free_blob; @@ -265,7 +265,7 @@ void drm_crtc_close(drm_crtc_t* restrict crtc) int drm_get_gamma(drm_crtc_t* restrict crtc) { int r; - r = drmModeCrtcGetGamma(crtc->card->fd, crtc->id, crtc->gamma_stops, + r = drmModeCrtcGetGamma(crtc->card->fd, crtc->id, (uint32_t)(crtc->gamma_stops), crtc->red, crtc->green, crtc->blue); return -!!r; } @@ -280,7 +280,7 @@ int drm_get_gamma(drm_crtc_t* restrict crtc) int drm_set_gamma(drm_crtc_t* restrict crtc) { int r; - r = drmModeCrtcSetGamma(crtc->card->fd, crtc->id, crtc->gamma_stops, + r = drmModeCrtcSetGamma(crtc->card->fd, crtc->id, (uint32_t)(crtc->gamma_stops), crtc->red, crtc->green, crtc->blue); return -!!r; } diff --git a/src/framebuffer.c b/src/framebuffer.c index f783671..55964d2 100644 --- a/src/framebuffer.c +++ b/src/framebuffer.c @@ -84,11 +84,11 @@ int fb_open(size_t index, framebuffer_t* restrict fb) if (fb->fd == -1) goto fail; - if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fix_info) || - ioctl(fb->fd, FBIOGET_VSCREENINFO, &var_info)) + 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, fix_info.smem_len, PROT_WRITE, MAP_SHARED, fb->fd, 0); + 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; @@ -133,9 +133,9 @@ void fb_close(framebuffer_t* restrict fb) uint32_t fb_colour(int red, int green, int blue) { uint32_t rc = 0; - rc |= red, rc <<= 8; - rc |= green, rc <<= 8; - rc |= blue; + rc |= (uint32_t)red, rc <<= 8; + rc |= (uint32_t)green, rc <<= 8; + rc |= (uint32_t)blue; return rc; } diff --git a/src/framebuffer.h b/src/framebuffer.h index f6b99ea..872ff78 100644 --- a/src/framebuffer.h +++ b/src/framebuffer.h @@ -93,7 +93,7 @@ void fb_close(framebuffer_t* restrict fb); * @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 fb_colour(int red, int green, int blue) __attribute__((const)); /** * Print a filled in rectangle to a framebuffer diff --git a/src/gamma.c b/src/gamma.c index 66f2f38..660c013 100644 --- a/src/gamma.c +++ b/src/gamma.c @@ -38,7 +38,7 @@ void gamma_analyse(size_t stops, const uint16_t* restrict ramp, double* restrict middle = (double)(ramp[stops / 2]) / (double)0xFFFF; middle = (middle - min) / (max - min); - *gamma = log(2.0) / log(middle); + *gamma = log((double)2) / log(middle); } @@ -55,7 +55,7 @@ void gamma_generate(size_t stops, uint16_t* restrict ramp, double gamma, double contrast, double brightness) { double diff = contrast - brightness; - double gamma_ = 1.0 / gamma; + double gamma_ = (double)1 / gamma; size_t i; int32_t y; double y_; @@ -67,7 +67,7 @@ void gamma_generate(size_t stops, uint16_t* restrict ramp, double gamma, y = (int32_t)(y * 0xFFFF); if (y < 0x0000) y = 0x0000; if (y > 0xFFFF) y = 0xFFFF; - ramp[i] = y; + ramp[i] = (uint16_t)y; } } diff --git a/src/state.c b/src/state.c new file mode 100644 index 0000000..4ca3a75 --- /dev/null +++ b/src/state.c @@ -0,0 +1,135 @@ +/** + * 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 number of elements in `crtcs` + */ +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); + } + } + + 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; + + free(crtcs), crtcs = NULL; + free(cards), cards = NULL; + free(framebuffers), framebuffers = NULL; +} + diff --git a/src/state.h b/src/state.h new file mode 100644 index 0000000..fd5a18e --- /dev/null +++ b/src/state.h @@ -0,0 +1,74 @@ +/** + * 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 number of elements in `crtcs` + */ +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 + |