aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/calibrator.c136
-rw-r--r--src/calibrator.h19
-rw-r--r--src/drmgamma.c8
-rw-r--r--src/framebuffer.c12
-rw-r--r--src/framebuffer.h2
-rw-r--r--src/gamma.c6
-rw-r--r--src/state.c135
-rw-r--r--src/state.h74
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
+