5 Commits
v0.2 ... master

Author SHA1 Message Date
rexy712
f111390259 add destdir support 2019-01-15 11:25:31 -08:00
rexy712
2818a6910b version bump 2019-01-15 11:15:03 -08:00
rexy712
e06b405b20 Redid sysfs access to work outside of udev rule context 2019-01-15 11:07:15 -08:00
rexy712
5cfcf558ff updated readme equivalence example 2018-04-28 20:56:51 -07:00
rexy712
e3e1408c10 request updated info from X instead of the stale stuff that we were getting 2018-04-28 20:54:46 -07:00
3 changed files with 88 additions and 86 deletions

2
README
View File

@@ -1,2 +1,2 @@
this program does the same thing as this:
xrandr --props | awk '$2 ~ /^connected/ {printf $1 ":";getline;getline;while($2 == ""){printf $1;getline;};printf "\n";}'
xrandr --props | awk '$2 ~ /connected/ {printf $1 ":";getline;getline;while($2 == ""){printf $1;getline;};printf "\n";}'

View File

@@ -67,7 +67,8 @@ $(DEPDIR):
.PHONY: install
install: $(MAIN_EXECUTABLE)
install -m 755 "$(MAIN_EXECUTABLE)" /usr/bin/
$(call mkdir,"${DESTDIR}/usr/bin")
install -m 755 "$(MAIN_EXECUTABLE)" ${DESTDIR}/usr/bin/
.PHONY: clean
clean:

View File

@@ -1,6 +1,6 @@
/*
rex-edid extracts the EDID data and corresponding display name from the X server
Copyright (C) 2018 rexy712
Copyright (C) 2018-2019 rexy712
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
@@ -22,9 +22,10 @@
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#define REX_EDID_VERSION_MAJ 0u
#define REX_EDID_VERSION_MIN 2u
#define REX_EDID_VERSION_MIN 3u
#define RANDR_MIN_VER_MAJ 1u
#define RANDR_MIN_VER_MIN 3u
@@ -114,7 +115,7 @@ int rex_edid_xrandr(void){
randr_ver_min, /*return location for RandR version*/
randr_ver_maj; /*see above*/
int i; /*counter*/
xcb_randr_get_screen_resources_current_reply_t* randr_resources_reply; /*X server reply to our resource query*/
xcb_randr_get_screen_resources_reply_t* randr_resources_reply; /*X server reply to our resource query*/
/*initialize connection to x server*/
@@ -133,13 +134,13 @@ int rex_edid_xrandr(void){
/*get all this bs so we can get what we actually want*/
root = get_screen_root_window(connection, screen_num);
randr_resources_reply = xcb_randr_get_screen_resources_current_reply(connection, xcb_randr_get_screen_resources_current(connection, root), NULL);
randr_resources_reply = xcb_randr_get_screen_resources_reply(connection, xcb_randr_get_screen_resources(connection, root), NULL);
timestamp = randr_resources_reply->config_timestamp;
/*number of displays*/
num_randr_outputs = xcb_randr_get_screen_resources_current_outputs_length(randr_resources_reply);
num_randr_outputs = xcb_randr_get_screen_resources_outputs_length(randr_resources_reply);
/*list of displays*/
randr_outputs = xcb_randr_get_screen_resources_current_outputs(randr_resources_reply);
randr_outputs = xcb_randr_get_screen_resources_outputs(randr_resources_reply);
for(i = 0;i < num_randr_outputs;++i){
xcb_randr_get_output_info_reply_t* output_info_reply;
@@ -165,7 +166,6 @@ int rex_edid_xrandr(void){
unsigned int k;
/*get atom_name*/
atom_name_reply = xcb_get_atom_name_reply(connection, xcb_get_atom_name(connection, output_atoms[j]), NULL);
/*if the atom is the EDID data, we want to get it*/
if(!memcmp(xcb_get_atom_name_name(atom_name_reply), "EDID", 4)){
/*get property data for the current atom*/
@@ -190,102 +190,103 @@ int rex_edid_xrandr(void){
return 0;
}
/*get device name from DEVPATH environment variable and prepend '/sys' to it*/
char* get_device_path(int* len){
char* devpath;
int length;
char* tmp;
/*udev stores the device location in sysfs in DEVPATH environment variable*/
devpath = getenv("DEVPATH");
if(!devpath)
return NULL;
length = strlen(devpath) + 5;
tmp = malloc(length);
if(!tmp)
return NULL;
tmp[length-1] = 0;
snprintf(tmp, length, "/sys%s", devpath);
if(len)
*len = length-1;
return tmp;
}
/*extract device name from the device path (the last part of the pathname)*/
char* get_device_name(char* devpath, int strlength){
int i;
for(i = strlength-1;i >= 0;--i){
if(devpath[i] == '/'){
if(i == strlength)
return NULL;
return &(devpath[i])+1;
}
char** add_interface(char* str, size_t slen, char** list, size_t cap, size_t len){
if(len >= cap){
list = realloc(list, cap*2 * sizeof(char*));
}
return NULL;
list[len] = malloc(slen+1);
strncpy(list[len], str, slen);
list[len][slen] = 0;
return list;
}
void free_int_list(char** list, size_t len){
for(size_t i = 0;i < len;++i)
free(list[i]);
free(list);
}
int rex_edid_sysfs(void){
int devpath_len; /*length of device path name*/
int devname_len; /*length of device name*/
char* devpath; /*name of device path*/
char* devname; /*name of the device*/
char** dev_int_names = malloc(sizeof(char*)); /*name of device interfaces*/
size_t num_names = 0;
size_t names_size = 1;
DIR* dp; /*pointer to open device directory in sysfs*/
struct dirent* dir; /*accessor to sysfs directory*/
/*set up device names*/
devpath = get_device_path(&devpath_len);
if(!devpath){
fprintf(stderr, "DEVPATH is empty!\n");
return -3;
}
devname = get_device_name(devpath, devpath_len);
devname_len = strlen(devname);
/*open directory*/
dp = opendir(devpath);
dp = opendir("/sys/class/drm");
if(!dp){
fprintf(stderr, "Unable to open DEVPATH!\n");
fprintf(stderr, "Unable to open device path!\n");
return -2;
}
/*check all contents of device directory*/
while((dir = readdir(dp))){
if(!strncmp(dir->d_name, devname, devname_len)){
int edid_len; /*length of full path to edid file*/
char* edid_file; /*buffer for edid path name*/
unsigned char c; /*place to store char from file*/
/*set up edid file path*/
edid_len = strlen(dir->d_name)+1 + devpath_len + 6;
edid_file = malloc(edid_len);
snprintf(edid_file, edid_len, "%s/%s/edid", devpath, dir->d_name);
printf("%s:", dir->d_name + devname_len+1);
/*read in edid data from file*/
FILE* fd = fopen(edid_file, "r");
if(!fd){
fprintf(stderr, "Unable to open edid file\n");
free(edid_file);
printf("\n");
continue;
if(!strncmp(dir->d_name, "card", 4)){
size_t l = strlen(dir->d_name);
int add = 1;
for(size_t i = 4;i < l;++i){
if(dir->d_name[i] == '-'){
add = 0;
}
}
c = fgetc(fd);
while(!feof(fd)){
printf("%02x", c);
c = fgetc(fd);
if(add){
dev_int_names = add_interface(dir->d_name, l, dev_int_names, names_size, num_names);
++num_names;
}
/*cleanup*/
fclose(fd);
free(edid_file);
printf("\n");
}
}
closedir(dp);
free(devpath);
chdir("/sys/class/drm");
for(size_t i = 0;i < num_names;++i){
devname = dev_int_names[i];
devname_len = strlen(devname);
/*open directory*/
dp = opendir(devname);
if(!dp){
fprintf(stderr, "Unable to open %s!\n", devname);
continue;
}
/*check all contents of device directory*/
while((dir = readdir(dp))){
if(!strncmp(dir->d_name, devname, devname_len)){
int edid_len; /*length of full path to edid file*/
char* edid_file; /*buffer for edid path name*/
unsigned char c; /*place to store char from file*/
/*set up edid file path*/
edid_len = strlen(dir->d_name)+6;
edid_file = malloc(edid_len);
snprintf(edid_file, edid_len, "%s/edid", dir->d_name);
printf("%s:", dir->d_name + devname_len+1);
/*read in edid data from file*/
FILE* fd = fopen(edid_file, "r");
if(!fd){
fprintf(stderr, "Unable to open edid file\n");
free(edid_file);
continue;
}
c = fgetc(fd);
while(!feof(fd)){
printf("%02x", c);
c = fgetc(fd);
}
/*cleanup*/
fclose(fd);
free(edid_file);
printf("\n");
}
}
closedir(dp);
}
free_int_list(dev_int_names, num_names);
return 0;
}