diff options
Diffstat (limited to 'kms++/src/card.cpp')
-rw-r--r-- | kms++/src/card.cpp | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/kms++/src/card.cpp b/kms++/src/card.cpp index 04750af..f404d3a 100644 --- a/kms++/src/card.cpp +++ b/kms++/src/card.cpp @@ -7,7 +7,7 @@ #include <algorithm> #include <cerrno> #include <algorithm> -#include <sys/stat.h> +#include <glob.h> #include <xf86drm.h> #include <xf86drmMode.h> @@ -19,15 +19,31 @@ using namespace std; namespace kms { -unique_ptr<Card> Card::open_modesetting_card() +static vector<string> glob(const string& pattern) { - for (uint32_t i = 0; ; ++i) { - string path = "/dev/dri/card" + to_string(i); + glob_t glob_result; + memset(&glob_result, 0, sizeof(glob_result)); + + int r = glob(pattern.c_str(), 0, NULL, &glob_result); + if(r != 0) { + globfree(&glob_result); + throw runtime_error("failed to find DRM cards"); + } + + vector<string> filenames; + for(size_t i = 0; i < glob_result.gl_pathc; ++i) + filenames.push_back(string(glob_result.gl_pathv[i])); + + globfree(&glob_result); + + return filenames; +} - struct stat buffer; - if (stat(path.c_str(), &buffer)) - break; +unique_ptr<Card> Card::open_modesetting_card() +{ + vector<string> paths = glob("/dev/dri/card*"); + for (const string& path : paths) { unique_ptr<Card> card = unique_ptr<Card>(new Card(path)); if (card->get_connectors().size() > 0 && @@ -49,18 +65,13 @@ static int open_device_by_path(string path) // open Nth DRM card with the given driver name static int open_device_by_driver(string name, uint32_t idx) { - uint32_t matches = 0; - transform(name.begin(), name.end(), name.begin(), ::tolower); - for (uint32_t i = 0; ; ++i) { - string path = "/dev/dri/card" + to_string(i); + uint32_t num_matches = 0; + vector<string> paths = glob("/dev/dri/card*"); - int fd = open(path.c_str(), O_RDWR | O_CLOEXEC); - if (fd < 0) { - // presume no more card nodes - throw invalid_argument("no card found for " + name + ":" + to_string(idx)); - } + for (const string& path : paths) { + int fd = open_device_by_path(path); drmVersionPtr ver = drmGetVersion(fd); string drv_name = string(ver->name, ver->name_len); @@ -69,13 +80,15 @@ static int open_device_by_driver(string name, uint32_t idx) transform(drv_name.begin(), drv_name.end(), drv_name.begin(), ::tolower); if (name == drv_name) { - if (idx == matches) + if (idx == num_matches) return fd; - matches++; + num_matches++; } close(fd); } + + throw invalid_argument("Failed to find a DRM device " + name + ":" + to_string(idx)); } Card::Card() |