From 33b7e8f777727b2e53365b2dbd355a665c51501e Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 02:07:48 +0100 Subject: begin on drm support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/blueshift_drm_c.c (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c new file mode 100644 index 0000000..5007a24 --- /dev/null +++ b/src/blueshift_drm_c.c @@ -0,0 +1,44 @@ +/** + * 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 Affero 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 . + */ +#include +#include +#include +#include + +#include +#include + +/* Requires video group */ + + +int main(int argc, char** argv) +{ + DIR* dir; + + (void) argc; + (void) argv; + + if ((dir = opendir("/dev/dri")) == NULL) + { + perror("opendir"); + return 1; + } + + free(dir); + return 0; +} + -- cgit v1.2.3-70-g09d2 From 2e53afb10dbff3346079601579ee5eaaa5c1884e Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 02:28:35 +0100 Subject: count graphic cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 5007a24..629030c 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -16,29 +16,57 @@ */ #include #include +#include +#include +#include #include -#include +#include +#include #include #include +#ifndef PATH_MAX + #define PATH_MAX 4096 +#endif + /* Requires video group */ -int main(int argc, char** argv) +/** + * Get the number of cards present on the system + * + * @return The number of cards present on the system + */ +long card_count() { - DIR* dir; + char* pathname = alloca(PATH_MAX * sizeof(char)); + long len = strlen("/dev/dri/card"); + long count = 0; + struct stat attr; - (void) argc; - (void) argv; + memcpy(pathname, "/dev/dri/card", len); - if ((dir = opendir("/dev/dri")) == NULL) + for (;;) { - perror("opendir"); - return 1; + sprintf(pathname + len, "%li", count); + if (stat(pathname, &attr)) + break; + count++; } - free(dir); + return count; +} + + +int main(int argc, char** argv) +{ + (void) argc; + (void) argv; + + + printf("%li\n", card_count()); + return 0; } -- cgit v1.2.3-70-g09d2 From b9638429122dc3a6064784962bfac70fecf1659d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 02:32:02 +0100 Subject: m MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 629030c..19b8e19 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -38,7 +38,7 @@ * * @return The number of cards present on the system */ -long card_count() +long blueshift_drm_card_count() { char* pathname = alloca(PATH_MAX * sizeof(char)); long len = strlen("/dev/dri/card"); @@ -65,7 +65,7 @@ int main(int argc, char** argv) (void) argv; - printf("%li\n", card_count()); + printf("%li\n", blueshift_drm_card_count()); return 0; } -- cgit v1.2.3-70-g09d2 From ec9def9775d090e2be2e2351e24d400f643a48b1 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 02:34:07 +0100 Subject: do not use limits.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 19b8e19..ce37f43 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -20,16 +20,11 @@ #include #include #include -#include #include #include #include -#ifndef PATH_MAX - #define PATH_MAX 4096 -#endif - /* Requires video group */ @@ -40,8 +35,8 @@ */ long blueshift_drm_card_count() { - char* pathname = alloca(PATH_MAX * sizeof(char)); long len = strlen("/dev/dri/card"); + char* pathname = alloca((len + 21) * sizeof(char)); long count = 0; struct stat attr; -- cgit v1.2.3-70-g09d2 From 8909996ec9ff7634473564735ffca0f03043d4dd Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 02:43:44 +0100 Subject: use paths from .h files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index ce37f43..b00660d 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -33,18 +33,16 @@ * * @return The number of cards present on the system */ -long blueshift_drm_card_count() +int blueshift_drm_card_count() { - long len = strlen("/dev/dri/card"); - char* pathname = alloca((len + 21) * sizeof(char)); - long count = 0; + long maxlen = strlen(DRM_DIR_NAME) + strlen(DRM_DEV_NAME) + 10; + char* pathname = alloca(maxlen * sizeof(char)); + int count = 0; struct stat attr; - memcpy(pathname, "/dev/dri/card", len); - for (;;) { - sprintf(pathname + len, "%li", count); + sprintf(pathname, DRM_DEV_NAME, DRM_DIR_NAME, count); if (stat(pathname, &attr)) break; count++; -- cgit v1.2.3-70-g09d2 From 6b539536349378d54d4b46b9375ae573f34d6e43 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 03:29:24 +0100 Subject: crtc and connector count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index b00660d..d143ddc 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -20,12 +20,29 @@ #include #include #include +#include #include +#ifndef O_CLOEXEC + #define O_CLOEXEC 02000000 +#endif + +/* Requires video group */ #include #include -/* Requires video group */ + + +/** + * File descriptor for the DRM connection + */ +static int drm_fd; + +/** + * DRM mode resources + */ +static drmModeRes* drm_res = NULL; + /** @@ -52,13 +69,89 @@ int blueshift_drm_card_count() } +/** + * Open connection to a graphics card + * + * @param card The index of the graphics card + * @return Zero on success + */ +int blueshift_drm_open(int card) +{ + long maxlen = strlen(DRM_DIR_NAME) + strlen(DRM_DEV_NAME) + 10; + char* pathname = alloca(maxlen * sizeof(char)); + + sprintf(pathname, DRM_DEV_NAME, DRM_DIR_NAME, card); + + drm_fd = open(pathname, O_RDWR | O_CLOEXEC); + if (drm_fd < 0) + { + perror("open"); + return 1; + } + + return 0; +} + + +/** + * Close connection to the graphics card + */ +void blueshift_drm_close() +{ + drmModeFreeResources(drm_res); + close(drm_fd); +} + + +/** + * Update the resource, required after `blueshift_drm_open` + */ +void blueshift_drm_update() +{ + if (drm_res) + drmModeFreeResources(drm_res); + + drm_res = drmModeGetResources(drm_fd); +} + + +/** + * Return the number of CRTC:s on the opened card + * + * @return The number of CRTC:s on the opened card + */ +int blueshift_drm_crtc_count() +{ + return drm_res->count_crtcs; +} + + +/** + * Return the number of connectors on the opened card + * + * @return The number of connectors on the opened card + */ +int blueshift_drm_connector_count() +{ + return drm_res->count_connectors; +} + + + int main(int argc, char** argv) { (void) argc; (void) argv; - printf("%li\n", blueshift_drm_card_count()); + printf("Card count: %i\n", blueshift_drm_card_count()); + + blueshift_drm_open(0); + blueshift_drm_update(); + printf("CRTC count: %i\n", blueshift_drm_crtc_count()); + printf("Connector count: %i\n", blueshift_drm_connector_count()); + + blueshift_drm_close(); return 0; } -- cgit v1.2.3-70-g09d2 From 24e4b242dd8dfd2c4b12faeac14da53d06a5fafd Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 03:40:25 +0100 Subject: gamma size retrieval MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index d143ddc..c9dea2f 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -137,6 +137,24 @@ int blueshift_drm_connector_count() } +/** + * Return the size of the gamma ramps on a CRTC + * + * @param crtc_index The index of the CRTC + * @return The size of the gamma ramps on a CRTC + */ +int blueshift_drm_gamma_size(int crtc_index) +{ + drmModeCrtc* crtc = drmModeGetCrtc(drm_fd, *(drm_res->crtcs + crtc_index)); + int gamma_size; + + gamma_size = crtc->gamma_size; + drmModeFreeCrtc(crtc); + + return gamma_size; +} + + int main(int argc, char** argv) { @@ -150,6 +168,7 @@ int main(int argc, char** argv) blueshift_drm_update(); printf("CRTC count: %i\n", blueshift_drm_crtc_count()); printf("Connector count: %i\n", blueshift_drm_connector_count()); + printf("Gamma size: %i\n", blueshift_drm_gamma_size(0)); blueshift_drm_close(); -- cgit v1.2.3-70-g09d2 From 06f3e5eb7b1efdba086ca178105617c0a85d0290 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 04:39:24 +0100 Subject: monitor data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index c9dea2f..afd27d9 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -166,10 +166,44 @@ int main(int argc, char** argv) blueshift_drm_open(0); blueshift_drm_update(); + printf("CRTC count: %i\n", blueshift_drm_crtc_count()); printf("Connector count: %i\n", blueshift_drm_connector_count()); printf("Gamma size: %i\n", blueshift_drm_gamma_size(0)); + drmModeConnector* connector = drmModeGetConnector(drm_fd, *(drm_res->connectors + 2)); + printf("Physical size: %i mm by %i mm\n", connector->mmWidth, connector->mmHeight); + /* Accurate dimension on area not covered by the edges */ + printf("Connected: %i\n", connector->connection == DRM_MODE_CONNECTED); + /* DRM_MODE_DISCONNECTED DRM_MODE_UNKNOWNCONNECTION */ + printf("Encoder: %i\n", connector->encoder_id); + static char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", + "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", + "VIRTUAL", "DSI"}; + printf("Type: %s (%i)\n", types[connector->connector_type], connector->connector_type); + int i; + for (i = 0; i < connector->count_props; i++) + { + drmModePropertyRes* prop; + prop = drmModeGetProperty(drm_fd, connector->props[i]); + if (!strcmp("EDID", prop->name)) + { + drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(drm_fd, connector->prop_values[i]); + char* value = alloca((blob->length * 2 + 1) * sizeof(char)); + uint32_t j; + for (j = 0; j < blob->length; j++) + { + *(value + j * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 4) & 15]; + *(value + j * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 0) & 15]; + } + *(value + blob->length * 2) = 0; + printf("%s: %s\n", prop->name, value); + drmModeFreePropertyBlob(blob); + } + drmModeFreeProperty(prop); + } + drmModeFreeConnector(connector); + blueshift_drm_close(); return 0; -- cgit v1.2.3-70-g09d2 From 21ad03fd620a545208579a8fe59dc2742de3b7b5 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 04:40:26 +0100 Subject: m MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index afd27d9..f045b97 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -177,9 +177,9 @@ int main(int argc, char** argv) printf("Connected: %i\n", connector->connection == DRM_MODE_CONNECTED); /* DRM_MODE_DISCONNECTED DRM_MODE_UNKNOWNCONNECTION */ printf("Encoder: %i\n", connector->encoder_id); - static char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", - "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", - "VIRTUAL", "DSI"}; + static const char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", + "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", + "VIRTUAL", "DSI"}; printf("Type: %s (%i)\n", types[connector->connector_type], connector->connector_type); int i; for (i = 0; i < connector->count_props; i++) -- cgit v1.2.3-70-g09d2 From b23be9747bd9c53e2437dfe95eaef87897095995 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 04:45:14 +0100 Subject: map to crtc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index f045b97..dcba7c5 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -176,7 +176,16 @@ int main(int argc, char** argv) /* Accurate dimension on area not covered by the edges */ printf("Connected: %i\n", connector->connection == DRM_MODE_CONNECTED); /* DRM_MODE_DISCONNECTED DRM_MODE_UNKNOWNCONNECTION */ - printf("Encoder: %i\n", connector->encoder_id); + if (connector->connection == DRM_MODE_CONNECTED) + { + drmModeEncoder* encoder = drmModeGetEncoder(drm_fd, connector->encoder_id); + uint32_t crtc_id = encoder->crtc_id; + int crtc; + drmModeFreeEncoder(encoder); + for (crtc = 0; crtc < drm_res->count_crtcs; crtc++) + if (*(drm_res->crtcs + crtc) == crtc_id) + printf("CRTC: %i\n", crtc); + } static const char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", "VIRTUAL", "DSI"}; -- cgit v1.2.3-70-g09d2 From 63f9e547a22be704d5b6a3362008963926179f44 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 04:59:55 +0100 Subject: read gamma ramps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index dcba7c5..8cb45c4 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -181,10 +181,41 @@ int main(int argc, char** argv) drmModeEncoder* encoder = drmModeGetEncoder(drm_fd, connector->encoder_id); uint32_t crtc_id = encoder->crtc_id; int crtc; + drmModeFreeEncoder(encoder); for (crtc = 0; crtc < drm_res->count_crtcs; crtc++) if (*(drm_res->crtcs + crtc) == crtc_id) - printf("CRTC: %i\n", crtc); + { + printf("CRTC: %i\n", crtc); + break; + } + + if (crtc < drm_res->count_crtcs) + { + int gamma_size = blueshift_drm_gamma_size(crtc); + uint16_t* red = alloca(gamma_size * sizeof(uint16_t)); + uint16_t* green = alloca(gamma_size * sizeof(uint16_t)); + uint16_t* blue = alloca(gamma_size * sizeof(uint16_t)); + int j; + + /* We need to initialise it to avoid valgrind warnings */ + for (j = 0; j < gamma_size; j++) + *(red + j) = *(green + j) = *(blue + j) = 0; + + if (!drmModeCrtcGetGamma(drm_fd, crtc_id, gamma_size, red, green, blue)) + { + printf("Red:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(red + j)); + printf("\nGreen:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(green + j)); + printf("\nBlue:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(blue + j)); + printf("\n"); + } + } } static const char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", -- cgit v1.2.3-70-g09d2 From 7eac2061687056eba5af5ae49fc8ebfc1f5cd77a Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 05:10:47 +0100 Subject: non-complete implementatation of setting gamma ramps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 8cb45c4..be6a5e1 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -171,7 +171,7 @@ int main(int argc, char** argv) printf("Connector count: %i\n", blueshift_drm_connector_count()); printf("Gamma size: %i\n", blueshift_drm_gamma_size(0)); - drmModeConnector* connector = drmModeGetConnector(drm_fd, *(drm_res->connectors + 2)); + drmModeConnector* connector = drmModeGetConnector(drm_fd, *(drm_res->connectors + 3)); printf("Physical size: %i mm by %i mm\n", connector->mmWidth, connector->mmHeight); /* Accurate dimension on area not covered by the edges */ printf("Connected: %i\n", connector->connection == DRM_MODE_CONNECTED); @@ -214,6 +214,16 @@ int main(int argc, char** argv) for (j = 0; j < gamma_size; j++) printf(" %u", *(blue + j)); printf("\n"); + + for (j = 0; j < gamma_size; j++) + *(red + j) /= 2; + for (j = 0; j < gamma_size; j++) + *(green + j) /= 2; + for (j = 0; j < gamma_size; j++) + *(blue + j) /= 2; + + printf("(%i)\n", drmModeCrtcSetGamma(drm_fd, crtc_id, gamma_size, red, green, blue)); + /* TODO what more is required to set gamma ramps? */ } } } -- cgit v1.2.3-70-g09d2 From 02c8cf17bd3d426e5b7ff8eec1d0e32cf8607b0a Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 06:42:59 +0100 Subject: translate stuff to functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 196 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 151 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index be6a5e1..21cc741 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -43,6 +43,11 @@ static int drm_fd; */ static drmModeRes* drm_res = NULL; +/** + * Connector information + */ +static drmModeConnector* connector = NULL; + /** @@ -155,6 +160,119 @@ int blueshift_drm_gamma_size(int crtc_index) } +/** + * Acquire information about a connector + * + * @param connector_index The index of the connector + */ +void blueshift_drm_open_connector(int connector_index) +{ + connector = drmModeGetConnector(drm_fd, *(drm_res->connectors + connector_index)); +} + + +/** + * Release information about the connector + */ +void blueshift_drm_close_connector() +{ + drmModeFreeConnector(connector); +} + + +/* Accurate dimension on area not covered by the edges */ + +/** + * Get the physical width the monitor connected to the connector + * + * @return The physical width of the monitor in millimetres, 0 if unknown or not connected + */ +int blueshift_drm_get_width() +{ + return connector->mmWidth; +} + + +/** + * Get the physical height the monitor connected to the connector + * + * @return The physical height of the monitor in millimetres, 0 if unknown or not connected + */ +int blueshift_drm_get_height() +{ + return connector->mmHeight; +} + + +/** + * Get whether a monitor is connected to a connector + * + * @return 1 if there is a connection, 0 otherwise, -1 if unknown + */ +int blueshift_drm_is_connected() +{ + switch (connector->connection) + { + case DRM_MODE_CONNECTED: + return 1; + case DRM_MODE_DISCONNECTED: + return 0; + case DRM_MODE_UNKNOWNCONNECTION: + default: + return -1; + } +} + + +/** + * Get the index of the CRTC of the monitor connected to the connector + * + * @return The index of the CRTC + */ +int blueshift_drm_get_crtc() +{ + drmModeEncoder* encoder = drmModeGetEncoder(drm_fd, connector->encoder_id); + uint32_t crtc_id = encoder->crtc_id; + int crtc; + + drmModeFreeEncoder(encoder); + + for (crtc = 0; crtc < drm_res->count_crtcs; crtc++) + if (*(drm_res->crtcs + crtc) == crtc_id) + return crtc; + + return -1; +} + + +/** + * Get the index of the type of the connector + * + * @return The connector type by index, 0 for unknown + */ +int blueshift_drm_get_connector_type_index() +{ + return connector->connector_type; +} + + +/** + * Get the name of the type of the connector + * + * @return The connector type by name, "Unknown" if not identifiable, + * "Unrecognised" if Blueshift does not recognise it. + */ +const char* blueshift_drm_get_connector_type_name() +{ + static const char* TYPE_NAMES[] = { + "Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", "Component", + "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", "VIRTUAL", "DSI"}; + + int type = connector->connector_type; + return (size_t)type < sizeof(TYPE_NAMES) / sizeof(char*) ? TYPE_NAMES[type] : "Unrecognised"; +} + + int main(int argc, char** argv) { @@ -166,31 +284,17 @@ int main(int argc, char** argv) blueshift_drm_open(0); blueshift_drm_update(); + blueshift_drm_open_connector(3); printf("CRTC count: %i\n", blueshift_drm_crtc_count()); printf("Connector count: %i\n", blueshift_drm_connector_count()); printf("Gamma size: %i\n", blueshift_drm_gamma_size(0)); - - drmModeConnector* connector = drmModeGetConnector(drm_fd, *(drm_res->connectors + 3)); - printf("Physical size: %i mm by %i mm\n", connector->mmWidth, connector->mmHeight); - /* Accurate dimension on area not covered by the edges */ - printf("Connected: %i\n", connector->connection == DRM_MODE_CONNECTED); - /* DRM_MODE_DISCONNECTED DRM_MODE_UNKNOWNCONNECTION */ - if (connector->connection == DRM_MODE_CONNECTED) - { - drmModeEncoder* encoder = drmModeGetEncoder(drm_fd, connector->encoder_id); - uint32_t crtc_id = encoder->crtc_id; - int crtc; - - drmModeFreeEncoder(encoder); - for (crtc = 0; crtc < drm_res->count_crtcs; crtc++) - if (*(drm_res->crtcs + crtc) == crtc_id) - { - printf("CRTC: %i\n", crtc); - break; - } - - if (crtc < drm_res->count_crtcs) + printf("Physical size: %i mm by %i mm\n", blueshift_drm_get_width(), blueshift_drm_get_height()); + printf("Connected: %i\n", blueshift_drm_is_connected()); + if (blueshift_drm_is_connected() == 1) + {; + int crtc = blueshift_drm_get_crtc(); + if (crtc >= 0) { int gamma_size = blueshift_drm_gamma_size(crtc); uint16_t* red = alloca(gamma_size * sizeof(uint16_t)); @@ -198,11 +302,13 @@ int main(int argc, char** argv) uint16_t* blue = alloca(gamma_size * sizeof(uint16_t)); int j; + printf("CRTC: %i\n", crtc); + /* We need to initialise it to avoid valgrind warnings */ for (j = 0; j < gamma_size; j++) *(red + j) = *(green + j) = *(blue + j) = 0; - if (!drmModeCrtcGetGamma(drm_fd, crtc_id, gamma_size, red, green, blue)) + if (!drmModeCrtcGetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue)) { printf("Red:"); for (j = 0; j < gamma_size; j++) @@ -222,38 +328,38 @@ int main(int argc, char** argv) for (j = 0; j < gamma_size; j++) *(blue + j) /= 2; - printf("(%i)\n", drmModeCrtcSetGamma(drm_fd, crtc_id, gamma_size, red, green, blue)); + drmModeCrtcSetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue); /* TODO what more is required to set gamma ramps? */ } } - } - static const char* types[] = {"Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", - "Component", "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", - "VIRTUAL", "DSI"}; - printf("Type: %s (%i)\n", types[connector->connector_type], connector->connector_type); - int i; - for (i = 0; i < connector->count_props; i++) - { - drmModePropertyRes* prop; - prop = drmModeGetProperty(drm_fd, connector->props[i]); - if (!strcmp("EDID", prop->name)) + + int i; + for (i = 0; i < connector->count_props; i++) { - drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(drm_fd, connector->prop_values[i]); - char* value = alloca((blob->length * 2 + 1) * sizeof(char)); - uint32_t j; - for (j = 0; j < blob->length; j++) + drmModePropertyRes* prop; + prop = drmModeGetProperty(drm_fd, connector->props[i]); + if (!strcmp("EDID", prop->name)) { - *(value + j * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 4) & 15]; - *(value + j * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 0) & 15]; + drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(drm_fd, connector->prop_values[i]); + char* value = alloca((blob->length * 2 + 1) * sizeof(char)); + uint32_t j; + for (j = 0; j < blob->length; j++) + { + *(value + j * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 4) & 15]; + *(value + j * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 0) & 15]; + } + *(value + blob->length * 2) = 0; + printf("%s: %s\n", prop->name, value); + drmModeFreePropertyBlob(blob); } - *(value + blob->length * 2) = 0; - printf("%s: %s\n", prop->name, value); - drmModeFreePropertyBlob(blob); + drmModeFreeProperty(prop); } - drmModeFreeProperty(prop); } - drmModeFreeConnector(connector); + printf("Connector type: %s (%i)\n", + blueshift_drm_get_connector_type_name(), + blueshift_drm_get_connector_type_index()); + blueshift_drm_close_connector(); blueshift_drm_close(); return 0; -- cgit v1.2.3-70-g09d2 From 11905297e0b65a87dd83bde48d78cfbcc1598cfb Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 07:26:03 +0100 Subject: translate stuff to functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 120 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 21cc741..a4518d6 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -273,6 +273,70 @@ const char* blueshift_drm_get_connector_type_name() } +/** + * Get the current gamma ramps of the + * + * @param crtc_index The index of the CRTC to read from + * @param gamma_size The size a gamma ramp + * @param red Storage location for the red gamma ramp + * @param green Storage location for the green gamma ramp + * @param blue Storage location for the blue gamma ramp + * @return Zero on success + */ +int blueshift_drm_get_gamma_ramps(int crtc_index, int gamma_size, uint16_t* red, uint16_t* green, uint16_t* blue) +{ + int i; + + /* We need to initialise it to avoid valgrind warnings */ + for (i = 0; i < gamma_size; i++) + *(red + i) = *(green + i) = *(blue + i) = 0; + + return drmModeCrtcGetGamma(drm_fd, *(drm_res->crtcs + crtc_index), gamma_size, red, green, blue); +} + + +/** + * Get the extended display identification data for the monitor connected to the connector + * + * @param edid Storage location for the EDID, it should be 128 bytes, 256 bytes + zero termination if hex + * @param size The size allocated to `edid` excluding your zero termination + * @param hex Whether to convert to hexadecimal representation, this is preferable + * @return The length of the found value, 0 if none, as if hex is false + */ +long blueshift_drm_get_edid(char* edid, long size, int hex) +{ + long rc = 0; + int prop_i; + for (prop_i = 0; prop_i < connector->count_props; prop_i++) + { + drmModePropertyRes* prop = drmModeGetProperty(drm_fd, connector->props[prop_i]); + if (!strcmp("EDID", prop->name)) + { + drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(drm_fd, connector->prop_values[prop_i]); + if (hex) + { + rc += blob->length; + uint32_t n = size / 2; + uint32_t i; + if (n < blob->length) + n = blob->length; + for (i = 0; i < n ; i++) + { + *(edid + i * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + i) >> 4) & 15]; + *(edid + i * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + i) >> 0) & 15]; + } + } + else + memcpy(edid, blob->data, (blob->length < size ? blob->length : size) * sizeof(char)); + drmModeFreePropertyBlob(blob); + prop_i = connector->count_props; /* stop to for loop */ + } + drmModeFreeProperty(prop); + } + return rc; +} + + int main(int argc, char** argv) { @@ -297,19 +361,15 @@ int main(int argc, char** argv) if (crtc >= 0) { int gamma_size = blueshift_drm_gamma_size(crtc); - uint16_t* red = alloca(gamma_size * sizeof(uint16_t)); - uint16_t* green = alloca(gamma_size * sizeof(uint16_t)); - uint16_t* blue = alloca(gamma_size * sizeof(uint16_t)); - int j; + uint16_t* red = alloca(3 * gamma_size * sizeof(uint16_t)); + uint16_t* green = red + gamma_size; + uint16_t* blue = green + gamma_size; printf("CRTC: %i\n", crtc); - /* We need to initialise it to avoid valgrind warnings */ - for (j = 0; j < gamma_size; j++) - *(red + j) = *(green + j) = *(blue + j) = 0; - - if (!drmModeCrtcGetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue)) + if (!blueshift_drm_get_gamma_ramps(crtc, gamma_size, red, green, blue)) { + int j; printf("Red:"); for (j = 0; j < gamma_size; j++) printf(" %u", *(red + j)); @@ -333,27 +393,27 @@ int main(int argc, char** argv) } } - int i; - for (i = 0; i < connector->count_props; i++) - { - drmModePropertyRes* prop; - prop = drmModeGetProperty(drm_fd, connector->props[i]); - if (!strcmp("EDID", prop->name)) - { - drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(drm_fd, connector->prop_values[i]); - char* value = alloca((blob->length * 2 + 1) * sizeof(char)); - uint32_t j; - for (j = 0; j < blob->length; j++) - { - *(value + j * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 4) & 15]; - *(value + j * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + j) >> 0) & 15]; - } - *(value + blob->length * 2) = 0; - printf("%s: %s\n", prop->name, value); - drmModeFreePropertyBlob(blob); - } - drmModeFreeProperty(prop); - } + { + long size = 128; + char* edid = malloc((size * 2 + 1) * sizeof(char)); + long n; + + *(edid + size * 2) = 0; + + n = blueshift_drm_get_edid(edid, size, 1); + if (n) + { + if (n > size) + { + size = n; + edid = realloc(edid, (size * 2 + 1) * sizeof(char)); + blueshift_drm_get_edid(edid, size, 1); + } + *(edid + n * 2) = 0; + printf("EDID: %s\n", edid); + } + free(edid); + } } printf("Connector type: %s (%i)\n", blueshift_drm_get_connector_type_name(), -- cgit v1.2.3-70-g09d2 From 573cf9da1ea68f2e9d2f2bb0e2046cb98b1bee25 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 07:48:55 +0100 Subject: read add outputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 155 ++++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index a4518d6..935afdc 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -340,86 +340,105 @@ long blueshift_drm_get_edid(char* edid, long size, int hex) int main(int argc, char** argv) { + int card_n = blueshift_drm_card_count(); + int card_i; + (void) argc; (void) argv; - - printf("Card count: %i\n", blueshift_drm_card_count()); - - blueshift_drm_open(0); - blueshift_drm_update(); - blueshift_drm_open_connector(3); - - printf("CRTC count: %i\n", blueshift_drm_crtc_count()); - printf("Connector count: %i\n", blueshift_drm_connector_count()); - printf("Gamma size: %i\n", blueshift_drm_gamma_size(0)); - printf("Physical size: %i mm by %i mm\n", blueshift_drm_get_width(), blueshift_drm_get_height()); - printf("Connected: %i\n", blueshift_drm_is_connected()); - if (blueshift_drm_is_connected() == 1) - {; - int crtc = blueshift_drm_get_crtc(); - if (crtc >= 0) + printf("Card count: %i\n", card_n); + for (card_i = 0; card_i < card_n; card_i++) + { + int connector_n; + int connector_i; + + printf("Card: %i\n", card_i); + + blueshift_drm_open(0); + blueshift_drm_update(); + + connector_n = blueshift_drm_connector_count(); + + printf(" CRTC count: %i\n", blueshift_drm_crtc_count()); + printf(" Connector count: %i\n", connector_n); + + for (connector_i = 0; connector_i < connector_n; connector_i++) { - int gamma_size = blueshift_drm_gamma_size(crtc); - uint16_t* red = alloca(3 * gamma_size * sizeof(uint16_t)); - uint16_t* green = red + gamma_size; - uint16_t* blue = green + gamma_size; + int crtc; - printf("CRTC: %i\n", crtc); + blueshift_drm_open_connector(connector_i); - if (!blueshift_drm_get_gamma_ramps(crtc, gamma_size, red, green, blue)) + printf(" Connector: %i\n", + connector_i); + printf(" Connected: %i\n", + blueshift_drm_is_connected()); + printf(" Connector type: %s (%i)\n", + blueshift_drm_get_connector_type_name(), + blueshift_drm_get_connector_type_index()); + + if (blueshift_drm_is_connected() == 1) { - int j; - printf("Red:"); - for (j = 0; j < gamma_size; j++) - printf(" %u", *(red + j)); - printf("\nGreen:"); - for (j = 0; j < gamma_size; j++) - printf(" %u", *(green + j)); - printf("\nBlue:"); - for (j = 0; j < gamma_size; j++) - printf(" %u", *(blue + j)); - printf("\n"); + long size = 128; + char* edid = malloc((size * 2 + 1) * sizeof(char)); + long n; - for (j = 0; j < gamma_size; j++) - *(red + j) /= 2; - for (j = 0; j < gamma_size; j++) - *(green + j) /= 2; - for (j = 0; j < gamma_size; j++) - *(blue + j) /= 2; + printf(" Physical size: %i mm by %i mm\n", + blueshift_drm_get_width(), + blueshift_drm_get_height()); - drmModeCrtcSetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue); - /* TODO what more is required to set gamma ramps? */ + if ((n = blueshift_drm_get_edid(edid, size, 1))) + { + if (n > size) + { + size = n; + edid = realloc(edid, (size * 2 + 1) * sizeof(char)); + blueshift_drm_get_edid(edid, size, 1); + } + *(edid + n * 2) = 0; + printf(" EDID: %s\n", edid); + } + free(edid); + + if ((crtc = blueshift_drm_get_crtc()) >= 0) + { + int gamma_size = blueshift_drm_gamma_size(crtc); + uint16_t* red = alloca(3 * gamma_size * sizeof(uint16_t)); + uint16_t* green = red + gamma_size; + uint16_t* blue = green + gamma_size; + + printf(" CRTC: %i\n", crtc); + printf(" Gamma size: %i\n", gamma_size); + + if (!blueshift_drm_get_gamma_ramps(crtc, gamma_size, red, green, blue)) + { + int j; + printf(" Red:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(red + j)); + printf("\n Green:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(green + j)); + printf("\n Blue:"); + for (j = 0; j < gamma_size; j++) + printf(" %u", *(blue + j)); + printf("\n"); + + for (j = 0; j < gamma_size; j++) + *(red + j) /= 2; + for (j = 0; j < gamma_size; j++) + *(green + j) /= 2; + for (j = 0; j < gamma_size; j++) + *(blue + j) /= 2; + + drmModeCrtcSetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue); + // TODO what more is required to set gamma ramps? + } + } } + + blueshift_drm_close_connector(); } - - { - long size = 128; - char* edid = malloc((size * 2 + 1) * sizeof(char)); - long n; - - *(edid + size * 2) = 0; - - n = blueshift_drm_get_edid(edid, size, 1); - if (n) - { - if (n > size) - { - size = n; - edid = realloc(edid, (size * 2 + 1) * sizeof(char)); - blueshift_drm_get_edid(edid, size, 1); - } - *(edid + n * 2) = 0; - printf("EDID: %s\n", edid); - } - free(edid); - } } - printf("Connector type: %s (%i)\n", - blueshift_drm_get_connector_type_name(), - blueshift_drm_get_connector_type_index()); - - blueshift_drm_close_connector(); blueshift_drm_close(); return 0; -- cgit v1.2.3-70-g09d2 From 511f62a11d88a9a8d3fd84e02d9b14089b54d734 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 12 Mar 2014 08:38:40 +0100 Subject: cause of set gamma failure determined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blueshift_drm_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c index 935afdc..4e8c750 100644 --- a/src/blueshift_drm_c.c +++ b/src/blueshift_drm_c.c @@ -431,7 +431,7 @@ int main(int argc, char** argv) *(blue + j) /= 2; drmModeCrtcSetGamma(drm_fd, *(drm_res->crtcs + crtc), gamma_size, red, green, blue); - // TODO what more is required to set gamma ramps? + /* Fails if inside a graphical environment */ } } } -- cgit v1.2.3-70-g09d2