From 216b9c0d64b80163792135569ec6ad8ed83b445c Mon Sep 17 00:00:00 2001 From: uvos Date: Fri, 25 Apr 2025 14:49:34 +0200 Subject: [PATCH] inital commit --- CMakeLists.txt | 17 ++++++ main.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 main.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c25da00 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.10) + +project(drmcrtcinfo) + +set(SRC_FILES main.c) +set(LIBS -ldrm) + +add_executable(${PROJECT_NAME} ${SRC_FILES}) + +target_link_libraries( ${PROJECT_NAME} ${LIBS} -lstdc++fs) +target_include_directories(${PROJECT_NAME} PRIVATE "/usr/include/libdrm/") +add_definitions("-Wall -O2 -flto -fno-strict-aliasing") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") + + +set(CMAKE_INSTALL_PREFIX "/usr") +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) diff --git a/main.c b/main.c new file mode 100644 index 0000000..99d3438 --- /dev/null +++ b/main.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPMS_ID 2 + +int drm_get_device_connectors(int device, drmModeConnectorPtr** connectors) +{ + drmModeRes* resources; + resources = drmModeGetResources(device); + if(!resources) { + perror("Can not get resources from drm device"); + return -1; + } + + if(resources->count_connectors > 0) { + *connectors = malloc(sizeof(drmModeConnectorPtr)*resources->count_connectors); + if(!*connectors) { + fprintf(stderr, "Out of memory!\n"); + return -2; + } + for(int i = 0; i < resources->count_connectors; ++i) { + (*connectors)[i] = drmModeGetConnectorCurrent(device, resources->connectors[i]); + } + return resources->count_connectors; + } + else { + return -3; + } +} + +void drm_free_device_connectors(drmModeConnectorPtr* connectors, int count_connectors) +{ + for(int i = 0; i < count_connectors; ++i) { + drmModeFreeConnector(connectors[i]); + } + free(connectors); +} + +int drm_get_connector_propertys(int device, drmModeConnectorPtr connector, drmModePropertyPtr** properties) +{ + *properties = malloc(sizeof(drmModePropertyRes*)*connector->count_props); + if(!properties){ + fprintf(stderr, "Out of memory!\n"); + return -1; + } + + for(int i = 0; i < connector->count_props; ++i) { + (*properties)[i] = drmModeGetProperty(device, connector->props[i]); + } + + return connector->count_props; +} + +void drm_free_device_properties(drmModePropertyPtr* properties, int count_props) +{ + for(int i = 0; i < count_props; ++i) { + drmModeFreeProperty(properties[i]); + } + free(properties); +} + +int drm_open_device(char* fileName) +{ + int fd; + fd = open(fileName, O_RDWR); + if(fd < 0) { + fprintf(stderr, "Can not open drm device %s: ", fileName); + perror(NULL); + return -1; + } + return fd; +} + + +int main(int argc, char** argv) +{ + if(argc < 2) { + printf("Usage: %s [DEVICE]\n", argv[0]); + return 1; + } + int device = drm_open_device("/dev/dri/card2"); + if(device < 0) + return 2; + + drmModeConnectorPtr* connectors = NULL; + int count_connectors = drm_get_device_connectors(device, &connectors); + + printf("Device has %i connectors\n", count_connectors); + for(int i = 0; i < count_connectors; ++i){ + drmModePropertyPtr* properties = NULL; + int count_props = drm_get_connector_propertys(device, connectors[i], &properties); + printf("Connector: %u with %i properties\n", connectors[i]->connector_id, count_props); + for(int j = 0; j < count_props; ++j){ + printf(" id: %u name: %s\n", properties[j]->prop_id, properties[j]->name); + } + drm_free_device_properties(properties, count_props); + } + drm_free_device_connectors(connectors, count_connectors); + + drmSetClientCap(device, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + drmModeResPtr resources = drmModeGetResources(device); + if(!resources) { + printf("Failed to get the resources!\n"); + return 3; + } + drmModePlaneResPtr planeres = drmModeGetPlaneResources(device); + printf("\nDevice has %i planes\n", planeres->count_planes); + for(int i = 0; i < planeres->count_planes; ++i){ + printf("Plane: %u\n", planeres->planes[i]); + drmModePlanePtr plane = drmModeGetPlane(device, planeres->planes[i]); + if(!plane) { + printf("\tUnable to get plane\n"); + continue; + } + + if(!plane->crtc_id) { + printf("\tNot Connected to crtc\n"); + } + else { + printf("\tcrtc id\t\t%u\n", plane->crtc_id); + drmModeCrtcPtr crtc = drmModeGetCrtc(device, plane->crtc_id); + if(!crtc) { + printf("\tUnable to get crtc\n"); + continue; + } + if(crtc->mode_valid) { + printf("\tClock\t\t%u\n", crtc->mode.clock); + printf("\thdisplay\t%u\n", crtc->mode.hdisplay); + printf("\thsync_start\t%u\n", crtc->mode.hsync_start); + printf("\thsync_end\t%u\n", crtc->mode.hsync_end); + printf("\thtotal\t\t%u\n", crtc->mode.htotal); + printf("\thskew\t\t%u\n", crtc->mode.hskew); + printf("\tvdisplay\t%u\n", crtc->mode.vdisplay); + printf("\tvsync_start\t%u\n", crtc->mode.vsync_start); + printf("\tvsync_end\t%u\n", crtc->mode.vsync_end); + printf("\tvtotal\t\t%u\n", crtc->mode.vtotal); + printf("\tvscan\t\t%u\n", crtc->mode.vscan); + printf("\tvrefresh\t%u\n", crtc->mode.vrefresh); + printf("\tflags\t\t%u\n", crtc->mode.flags); + } + } + + drmModeFreePlane(plane); + + } + drmModeFreePlaneResources(planeres); + drmModeFreeResources(resources); + + close(device); + + return 0; +}