diff options
Diffstat (limited to 'src/blueshift_drm_c.c')
-rw-r--r-- | src/blueshift_drm_c.c | 575 |
1 files changed, 0 insertions, 575 deletions
diff --git a/src/blueshift_drm_c.c b/src/blueshift_drm_c.c deleted file mode 100644 index 5da1481..0000000 --- a/src/blueshift_drm_c.c +++ /dev/null @@ -1,575 +0,0 @@ -/** - * 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 "blueshift_drm_c.h" - - -/** - * Mapping from card connection identifiers to card connection resources - */ -static card_connection* card_connections = NULL; - -/** - * Next card connection identifiers - */ -static size_t card_connection_ptr = 0; - -/** - * Size of the storage allocated for card connection resouces - */ -static size_t card_connection_size = 0; - -/** - * Card connection identifier reuse stack - */ -static long* card_connection_reusables = NULL; - -/** - * The head of `card_connection_reusables` - */ -static size_t card_connection_reuse_ptr = 0; - -/** - * The allocation size of `card_connection_reusables` - */ -static size_t card_connection_reuse_size = 0; - - - -/** - * Free all resources, but you need to close all connections first - */ -void blueshift_drm_close(void) -{ - if (card_connections) - free(card_connections); - - if (card_connection_reusables) - free(card_connection_reusables); - - card_connections = NULL; - card_connection_ptr = 0; - card_connection_size = 0; - card_connection_reusables = NULL; - card_connection_reuse_ptr = 0; - card_connection_reuse_size = 0; -} - - -/** - * Get the number of cards present on the system - * - * @return The number of cards present on the system - */ -int blueshift_drm_card_count(void) -{ - char pathname[PATH_MAX]; - int count = 0; - struct stat _attr; - - for (;;) - { - snprintf(pathname, PATH_MAX, DRM_DEV_NAME, DRM_DIR_NAME, count); - if (stat(pathname, &_attr)) - break; - count++; - } - - return count; -} - - -/** - * Open connection to a graphics card - * - * @param card_index The index of the graphics card - * @return -1 on failure, otherwise an identifier for the connection to the card - */ -int blueshift_drm_open_card(int card_index) -{ - char pathname[PATH_MAX]; - int fd; - int rc; - - snprintf(pathname, PATH_MAX, DRM_DEV_NAME, DRM_DIR_NAME, card_index); - - fd = open(pathname, O_RDWR | O_CLOEXEC); - if (fd < 0) - { - perror("open"); - return -1; - } - - if (card_connection_reuse_ptr) - rc = (int)*(card_connection_reusables + --card_connection_reuse_ptr); - else - { - if (card_connection_size == 0) - card_connections = malloc((card_connection_size = 8) * sizeof(card_connection)); - else if (card_connection_ptr == card_connection_size) - card_connections = realloc(card_connections, (card_connection_size <<= 1) * sizeof(card_connection)); - rc = (int)(card_connection_ptr++); - } - - (card_connections + rc)->fd = fd; - (card_connections + rc)->res = NULL; - (card_connections + rc)->connectors = NULL; - - return rc; -} - - -/** - * Update the resource, required after `blueshift_drm_open_card` - * - * @param connection The identifier for the connection to the card - */ -void blueshift_drm_update_card(int connection) -{ - card_connection* card = card_connections + connection; - - if (card->res) - drmModeFreeResources(card->res); - - card->res = drmModeGetResources(card->fd); -} - - -/** - * Close connection to the graphics card - * - * @param connection The identifier for the connection to the card - */ -void blueshift_drm_close_card(int connection) -{ - card_connection* card = card_connections + connection; - - drmModeFreeResources(card->res); - if (card->connectors) - free(card->connectors); - close(card->fd); - - if ((size_t)connection + 1 == card_connection_reuse_ptr) - card_connection_reuse_ptr--; - else - { - if (card_connection_reuse_size == 0) - card_connection_reusables = malloc((card_connection_reuse_size = 8) * sizeof(long)); - else if (card_connection_reuse_ptr == card_connection_reuse_size) - card_connection_reusables = realloc(card_connection_reusables, (card_connection_reuse_size <<= 1) * sizeof(long)); - *(card_connection_reusables + card_connection_reuse_ptr++) = connection; - } -} - - -/** - * Return the number of CRTC:s on the opened card - * - * @param connection The identifier for the connection to the card - * @return The number of CRTC:s on the opened card - */ -int blueshift_drm_crtc_count(int connection) -{ - return (card_connections + connection)->res->count_crtcs; -} - - -/** - * Return the number of connectors on the opened card - * - * @param connection The identifier for the connection to the card - * @return The number of connectors on the opened card - */ -int blueshift_drm_connector_count(int connection) -{ - return (card_connections + connection)->res->count_connectors; -} - - -/** - * Return the size of the gamma ramps on a CRTC - * - * @param connection The identifier for the connection to the card - * @param crtc_index The index of the CRTC - * @return The size of the gamma ramps on a CRTC - */ -int blueshift_drm_gamma_size(int connection, int crtc_index) -{ - card_connection* card = card_connections + connection; - drmModeCrtc* crtc = drmModeGetCrtc(card->fd, *(card->res->crtcs + crtc_index)); - int gamma_size = crtc->gamma_size; - - drmModeFreeCrtc(crtc); - return gamma_size; -} - - -/** - * Get the current gamma ramps of a monitor - * - * @param connection The identifier for the connection to the card - * @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 connection, int crtc_index, int gamma_size, uint16_t* red, uint16_t* green, uint16_t* blue) -{ - card_connection* card = card_connections + connection; - - /* We need to initialise it to avoid valgrind warnings */ - memset(red, 0, (size_t)gamma_size * sizeof(uint16_t)); - memset(green, 0, (size_t)gamma_size * sizeof(uint16_t)); - memset(blue, 0, (size_t)gamma_size * sizeof(uint16_t)); - - return drmModeCrtcGetGamma(card->fd, *(card->res->crtcs + crtc_index), (uint32_t)gamma_size, red, green, blue); -} - - -/** - * Set the gamma ramps of the of a monitor - * - * @param connection The identifier for the connection to the card - * @param crtc_index The index of the CRTC to read from - * @param gamma_size The size a gamma ramp - * @param red The red gamma ramp - * @param green The green gamma ramp - * @param blue The blue gamma ramp - * @return Zero on success - */ -int blueshift_drm_set_gamma_ramps(int connection, int crtc_index, int gamma_size, uint16_t* red, uint16_t* green, uint16_t* blue) -{ - card_connection* card = card_connections + connection; - - /* Fails if inside a graphical environment */ - return drmModeCrtcSetGamma(card->fd, *(card->res->crtcs + crtc_index), (uint32_t)gamma_size, red, green, blue); -} - - -/** - * Acquire information about a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - */ -void blueshift_drm_open_connector(int connection, int connector_index) -{ - card_connection* card = card_connections + connection; - - if (card->connectors == NULL) - card->connectors = malloc((size_t)(card->res->count_connectors) * sizeof(drmModeConnector*)); - *(card->connectors + connector_index) = drmModeGetConnector(card->fd, *(card->res->connectors + connector_index)); -} - - -/** - * Release information about a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - */ -void blueshift_drm_close_connector(int connection, int connector_index) -{ - drmModeFreeConnector(*((card_connections + connection)->connectors + connector_index)); -} - - -/** - * Get the physical width the monitor connected to a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @return The physical width of the monitor in millimetres, 0 if unknown or not connected - */ -int blueshift_drm_get_width(int connection, int connector_index) -{ - /* Accurate dimension on area not covered by the edges */ - return (int)((card_connections + connection)->connectors[connector_index]->mmWidth); -} - - -/** - * Get the physical height the monitor connected to a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @return The physical height of the monitor in millimetres, 0 if unknown or not connected - */ -int blueshift_drm_get_height(int connection, int connector_index) -{ - /* Accurate dimension on area not covered by the edges */ - return (int)((card_connections + connection)->connectors[connector_index]->mmHeight); -} - - -/** - * Get whether a monitor is connected to a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @return 1 if there is a connection, 0 otherwise, -1 if unknown - */ -int blueshift_drm_is_connected(int connection, int connector_index) -{ - switch ((card_connections + connection)->connectors[connector_index]->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 a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @return The index of the CRTC - */ -int blueshift_drm_get_crtc(int connection, int connector_index) -{ - card_connection* card = card_connections + connection; - drmModeEncoder* encoder = drmModeGetEncoder(card->fd, card->connectors[connector_index]->encoder_id); - uint32_t crtc_id = encoder->crtc_id; - drmModeRes* res = card->res; - int crtc; - int n; - - drmModeFreeEncoder(encoder); - - n = res->count_crtcs; - for (crtc = 0; crtc < n; crtc++) - if (*(res->crtcs + crtc) == crtc_id) - return crtc; - - return -1; -} - - -/** - * Get the index of the type of a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @return The connector type by index, 0 for unknown - */ -int blueshift_drm_get_connector_type_index(int connection, int connector_index) -{ - return (int)((card_connections + connection)->connectors[connector_index]->connector_type); -} - - -/** - * Get the name of the type of a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index 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(int connection, int connector_index) -{ - static const char* TYPE_NAMES[] = { - "Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", "Component", - "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", "VIRTUAL", "DSI"}; - - uint32_t type = ((card_connections + connection)->connectors[connector_index])->connector_type; - return (size_t)type < sizeof(TYPE_NAMES) / sizeof(char*) ? TYPE_NAMES[type] : "Unrecognised"; -} - - -/** - * Get the extended display identification data for the monitor connected to a connector - * - * @param connection The identifier for the connection to the card - * @param connector_index The index of the connector - * @param edid Storage location for the EDID, it should be 128 bytes, - * or 256 bytes if you are counting on the depricated EDID 2.0, - * If hexadecimal, twice that + zero termiation. - * @param size The size allocated to `edid` excluding your zero termination - * @param hexadecimal 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(int connection, int connector_index, char* edid, long size, int hexadecimal) -{ - card_connection* card = card_connections + connection; - drmModeConnector* connector = *(card->connectors + connector_index); - int fd = card->fd; - long rc = 0; - int prop_n = connector->count_props; - int prop_i; - - for (prop_i = 0; prop_i < prop_n; prop_i++) - { - drmModePropertyRes* prop = drmModeGetProperty(fd, connector->props[prop_i]); - if (!strcmp("EDID", prop->name)) - { - drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(fd, (uint32_t)(connector->prop_values[prop_i])); - if (hexadecimal) - { - uint32_t n = (uint32_t)size / 2; - uint32_t i; - rc += blob->length; - 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 - { - uint32_t len = blob->length < size ? blob->length : (uint32_t)size; - memcpy(edid, blob->data, (size_t)len * sizeof(char)); - } - drmModeFreePropertyBlob(blob); - prop_i = prop_n; /* stop the for-loop */ - } - drmModeFreeProperty(prop); - } - - return rc; -} - - -/* -int main(int argc, char** argv) -{ - int card_n = blueshift_drm_card_count(); - int* cards = alloca(card_n * sizeof(int*)); - int card_i; - - (void) argc; - (void) argv; - - printf("Card count: %i\n", card_n); - for (card_i = 0; card_i < card_n; card_i++) - { - *(cards + card_i) = blueshift_drm_open_card(card_i); - blueshift_drm_update_card(*(cards + card_i)); - } - - for (card_i = 0; card_i < card_n; card_i++) - { - int card = *(cards + card_i); - int connector_n; - int connector_i; - - printf("Card: %i\n", card_i); - - connector_n = blueshift_drm_connector_count(card); - - printf(" CRTC count: %i\n", blueshift_drm_crtc_count(card)); - printf(" Connector count: %i\n", connector_n); - - for (connector_i = 0; connector_i < connector_n; connector_i++) - { - blueshift_drm_open_connector(card, connector_i); - - printf(" Connector: %i\n", connector_i); - printf(" Connected: %i\n", blueshift_drm_is_connected(card, connector_i)); - printf(" Connector type: %s (%i)\n", - blueshift_drm_get_connector_type_name(card, connector_i), - blueshift_drm_get_connector_type_index(card, connector_i)); - - if (blueshift_drm_is_connected(card, connector_i) == 1) - { - long size = 128; - char* edid; - long n; - int crtc; - - printf(" Physical size: %i mm by %i mm\n", - blueshift_drm_get_width(card, connector_i), - blueshift_drm_get_height(card, connector_i)); - - edid = malloc((size * 2 + 1) * sizeof(char)); - if ((n = blueshift_drm_get_edid(card, connector_i, edid, size, 1))) - { - if (n > size) - { - size = n; - edid = realloc(edid, (size * 2 + 1) * sizeof(char)); - blueshift_drm_get_edid(card, connector_i, edid, size, 1); - } - *(edid + n * 2) = 0; - printf(" EDID: %s\n", edid); - } - free(edid); - - if ((crtc = blueshift_drm_get_crtc(card, connector_i)) >= 0) - { - int gamma_size = blueshift_drm_gamma_size(card, 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(card, crtc, gamma_size, red, green, blue)) - { - int i; - printf(" Red:"); - for (i = 0; i < gamma_size; i++) - printf(" %u", *(red + i)); - printf("\n Green:"); - for (i = 0; i < gamma_size; i++) - printf(" %u", *(green + i)); - printf("\n Blue:"); - for (i = 0; i < gamma_size; i++) - printf(" %u", *(blue + i)); - printf("\n"); - - for (i = 0; i < gamma_size; i++) - *(red + i) /= 2; - for (i = 0; i < gamma_size; i++) - *(green + i) /= 2; - for (i = 0; i < gamma_size; i++) - *(blue + i) /= 2; - - blueshift_drm_set_gamma_ramps(card, crtc, gamma_size, red, green, blue); - } - } - } - } - } - - for (card_i = 0; card_i < card_n; card_i++) - { - int card = *(cards + card_i); - int connector_n = blueshift_drm_connector_count(card); - int connector_i; - - for (connector_i = 0; connector_i < connector_n; connector_i++) - blueshift_drm_close_connector(card, connector_i); - - blueshift_drm_close_card(card); - } - - blueshift_drm_close(); - return 0; -} -*/ - |