added sysfs functionality

This commit is contained in:
Rexy712 2018-04-27 19:52:54 -07:00
parent ef1659db9c
commit 4654f50e7b
2 changed files with 149 additions and 11 deletions

View File

@ -65,6 +65,10 @@ $(OBJDIR):
$(DEPDIR): $(DEPDIR):
$(call mkdir,"$@") $(call mkdir,"$@")
.PHONY: install
install: $(MAIN_EXECUTABLE)
install -m 755 "$(MAIN_EXECUTABLE)" /usr/bin/
.PHONY: clean .PHONY: clean
clean: clean:
$(call rmdir,"$(DEPDIR)") $(call rmdir,"$(DEPDIR)")

View File

@ -21,6 +21,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dirent.h>
#define REX_EDID_VERSION_MAJ 0u
#define REX_EDID_VERSION_MIN 2u
#define RANDR_MIN_VER_MAJ 1u #define RANDR_MIN_VER_MAJ 1u
#define RANDR_MIN_VER_MIN 3u #define RANDR_MIN_VER_MIN 3u
@ -74,7 +78,14 @@ _Noreturn void help(int ret){
printf("Usage: rex-edid [--help]\n"); printf("Usage: rex-edid [--help]\n");
printf("\n"); printf("\n");
printf("Options:\n"); printf("Options:\n");
printf("%-20s%s\n", "\t--help|-h", "show this help message"); printf("\t--help|-h\n");
printf("\t\tshow this help message\n");
printf("\t--sysfs|-s\n");
printf("\t\tget edid data and device names from sysfs\n");
printf("\t\tNOT intended for use other than by udev rule\n");
printf("\t--xrandr|-s\n");
printf("\t\tget edid data and device names from X using randr extension\n");
printf("\t\trequires randr version %u.%u or newer\n", RANDR_MIN_VER_MAJ, RANDR_MIN_VER_MIN);
printf("\n"); printf("\n");
printf("rex-edid Copyright (C) 2018 rexy712\n"); printf("rex-edid Copyright (C) 2018 rexy712\n");
printf("This program comes with ABSOLUTELY NO WARRANTY; for details type refer to the LICENSE file.\n"); printf("This program comes with ABSOLUTELY NO WARRANTY; for details type refer to the LICENSE file.\n");
@ -82,8 +93,16 @@ _Noreturn void help(int ret){
printf("under certain conditions; see the LICENSE file for details.\n"); printf("under certain conditions; see the LICENSE file for details.\n");
exit(ret); exit(ret);
} }
_Noreturn void version(void){
printf("rex-edid version %u.%u\n", REX_EDID_VERSION_MAJ, REX_EDID_VERSION_MIN);
printf("Copyright (C) 2018 rexy712\n");
printf("This program comes with ABSOLUTELY NO WARRANTY; for details type refer to the LICENSE file.\n");
printf("This is free software, and you are welcome to redistribute it\n");
printf("under certain conditions; see the LICENSE file for details.\n");
exit(0);
}
int main(int argc, char* argv[]){ int rex_edid_xrandr(void){
xcb_connection_t* connection; /*connection to x server*/ xcb_connection_t* connection; /*connection to x server*/
xcb_window_t root; /*handle on root window of screen???*/ xcb_window_t root; /*handle on root window of screen???*/
xcb_timestamp_t timestamp; /*timestamp of resource reply???*/ xcb_timestamp_t timestamp; /*timestamp of resource reply???*/
@ -96,15 +115,6 @@ int main(int argc, char* argv[]){
xcb_randr_get_screen_resources_current_reply_t* randr_resources_reply; /*X server reply to our resource query*/ xcb_randr_get_screen_resources_current_reply_t* randr_resources_reply; /*X server reply to our resource query*/
for(i = 1;i < argc;++i){
if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
help(0);
else{
fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
help(1);
}
}
/*initialize connection to x server*/ /*initialize connection to x server*/
connection = xcb_connect(NULL, &screen_num); connection = xcb_connect(NULL, &screen_num);
if(xcb_connection_has_error(connection)){ if(xcb_connection_has_error(connection)){
@ -175,4 +185,128 @@ int main(int argc, char* argv[]){
free(randr_resources_reply); free(randr_resources_reply);
xcb_disconnect(connection); xcb_disconnect(connection);
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;
}
}
return NULL;
}
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*/
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);
if(!dp){
fprintf(stderr, "Unable to open DEVPATH!\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;
}
c = fgetc(fd);
while(!feof(fd)){
printf("%02x", c);
c = fgetc(fd);
}
/*cleanup*/
fclose(fd);
free(edid_file);
printf("\n");
}
}
closedir(dp);
free(devpath);
return 0;
}
int main(int argc, char* argv[]){
int i;
if(argc == 1){
help(1);
}
for(i = 1;i < argc;++i){
if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")){
help(0);
}else if(!strcmp(argv[i], "--sysfs") || !strcmp(argv[i], "-s")){
return rex_edid_sysfs();
}else if(!strcmp(argv[i], "--xrandr") || !strcmp(argv[i], "-x")){
return rex_edid_xrandr();
}else if(!strcmp(argv[i], "--version")){
version();
}else{
fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
help(1);
}
}
return 1;
} }