This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch devs/devilhorns/apos
in repository efl.
View the commit online.
commit cf602aeafc9ed67830f2501947f4ef56b21d3c27
Author: Christopher Michael <devilho...@comcast.net>
AuthorDate: Wed Aug 17 07:49:52 2022 -0400
ecore_drm2: Add code to open & close a drm device
---
src/lib/ecore_drm2/Ecore_Drm2.h | 8 ++
src/lib/ecore_drm2/ecore_drm2.c | 8 +-
src/lib/ecore_drm2/ecore_drm2_device.c | 153 ++++++++++++++++++++++++++++++++
src/lib/ecore_drm2/ecore_drm2_private.h | 12 +++
src/lib/ecore_drm2/meson.build | 1 +
5 files changed, 181 insertions(+), 1 deletion(-)
diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h
index 679b2e6249..0de98e1c5a 100644
--- a/src/lib/ecore_drm2/Ecore_Drm2.h
+++ b/src/lib/ecore_drm2/Ecore_Drm2.h
@@ -16,6 +16,14 @@
# endif // ifdef __GNUC__
# ifdef EFL_BETA_API_SUPPORT
+
+/* opaque structure to represent a drm device */
+typedef struct _Ecore_Drm2_Device Ecore_Drm2_Device;
+
+/* API functions */
+EAPI Ecore_Drm2_Device *ecore_drm2_device_open(const char *seat, unsigned int tty);
+EAPI void ecore_drm2_device_close(Ecore_Drm2_Device *dev);
+
# endif
#endif
diff --git a/src/lib/ecore_drm2/ecore_drm2.c b/src/lib/ecore_drm2/ecore_drm2.c
index 384afa621e..6d1096d2b7 100644
--- a/src/lib/ecore_drm2/ecore_drm2.c
+++ b/src/lib/ecore_drm2/ecore_drm2.c
@@ -7,6 +7,10 @@ static void *_drm_lib = NULL;
/* external variables */
int _ecore_drm2_log_dom = -1;
+/* external drm function prototypes (for dlopen) */
+void *(*sym_drmModeGetResources)(int fd) = NULL;
+void (*sym_drmModeFreeResources)(drmModeResPtr ptr) = NULL;
+
/* local static functions */
static Eina_Bool
_ecore_drm2_link(void)
@@ -40,6 +44,8 @@ _ecore_drm2_link(void)
fail = EINA_FALSE;
/* TODO: Sym needed libdrm functions */
+ SYM(_drm_lib, drmModeGetResources);
+ SYM(_drm_lib, drmModeFreeResources);
if (fail)
{
@@ -118,7 +124,7 @@ ecore_drm2_shutdown(void)
if (--_ecore_drm2_init_count != 0) return _ecore_drm2_init_count;
- dlclose(_drm_lib);
+ if (_drm_lib) dlclose(_drm_lib);
eina_log_domain_unregister(_ecore_drm2_log_dom);
_ecore_drm2_log_dom = -1;
diff --git a/src/lib/ecore_drm2/ecore_drm2_device.c b/src/lib/ecore_drm2/ecore_drm2_device.c
new file mode 100644
index 0000000000..6396c92d5e
--- /dev/null
+++ b/src/lib/ecore_drm2/ecore_drm2_device.c
@@ -0,0 +1,153 @@
+#include "ecore_drm2_private.h"
+
+/* local functions */
+static Eina_Bool
+_ecore_drm2_device_modeset_capable_get(int fd)
+{
+ Eina_Bool ret = EINA_TRUE;
+ drmModeRes *res;
+
+ res = sym_drmModeGetResources(fd);
+ if (!res) return EINA_FALSE;
+
+ if ((res->count_crtcs <= 0) || (res->count_connectors <= 0) ||
+ (res->count_encoders <= 0))
+ ret = EINA_FALSE;
+
+ sym_drmModeFreeResources(res);
+
+ return ret;
+}
+
+static const char *
+_ecore_drm2_device_path_get(Elput_Manager *em, const char *seat)
+{
+ Eina_List *devs, *l;
+ const char *denv = NULL, *dev = NULL, *chosen = NULL, *ret = NULL;
+ Eina_Bool found = EINA_FALSE, ms = EINA_FALSE;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(em, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
+
+ denv = getenv("ECORE_DRM2_CARD");
+ if (denv)
+ devs = eeze_udev_find_by_subsystem_sysname("drm", denv);
+ else
+ devs = eeze_udev_find_by_subsystem_sysname("drm", "card[0-9]*");
+
+ if (!devs) return NULL;
+
+ EINA_LIST_FOREACH(devs, l, dev)
+ {
+ int fd = -1;
+ const char *dpath, *dseat, *dparent;
+
+ dpath = eeze_udev_syspath_get_devpath(dev);
+ if (!dpath) continue;
+
+ dseat = eeze_udev_syspath_get_property(dev, "ID_SEAT");
+ if (!dseat) dseat = eina_stringshare_add("seat0");
+
+ if (strcmp(seat, dseat)) goto cont;
+
+ fd = elput_manager_open(em, dpath, -1);
+ if (fd < 0) goto cont;
+
+ ms = _ecore_drm2_device_modeset_capable_get(fd);
+ elput_manager_close(em, fd);
+ if (!ms) goto cont;
+
+ chosen = dev;
+
+ dparent = eeze_udev_syspath_get_parent_filtered(dev, "pci", NULL);
+ if (dparent)
+ {
+ const char *id;
+
+ id = eeze_udev_syspath_get_sysattr(dparent, "boot_vga");
+ if (id)
+ {
+ if (!strcmp(id, "1")) found = EINA_TRUE;
+ eina_stringshare_del(id);
+ }
+
+ eina_stringshare_del(dparent);
+ }
+
+cont:
+ eina_stringshare_del(dpath);
+ eina_stringshare_del(dseat);
+ if (found) break;
+ }
+
+ if (chosen)
+ ret = eeze_udev_syspath_get_devpath(chosen);
+
+ EINA_LIST_FREE(devs, dev)
+ eina_stringshare_del(dev);
+
+ return ret;
+}
+
+/* API functions */
+EAPI Ecore_Drm2_Device *
+ecore_drm2_device_open(const char *seat, unsigned int tty)
+{
+ const char *path;
+ Ecore_Drm2_Device *dev;
+
+ /* try to allocate space for return structure */
+ dev = calloc(1, sizeof(Ecore_Drm2_Device));
+ if (!dev) return NULL;
+
+ /* try to connect to Elput manager */
+ dev->em = elput_manager_connect(seat, tty);
+ if (!dev->em)
+ {
+ ERR("Could not connect to input manager");
+ goto man_err;
+ }
+
+ /* try to get drm device path */
+ path = _ecore_drm2_device_path_get(dev->em, seat);
+ if (!path)
+ {
+ ERR("Could not find drm device on seat %s", seat);
+ goto path_err;
+ }
+
+ /* try to open this device */
+ dev->fd = elput_manager_open(dev->em, path, -1);
+ if (dev->fd < 0)
+ {
+ ERR("Could not open drm device %s", path);
+ goto open_err;
+ }
+
+ /* TODO: elput_input_init, check atomic capable, etc */
+
+ return dev;
+
+open_err:
+ eina_stringshare_del(path);
+path_err:
+ elput_manager_disconnect(dev->em);
+man_err:
+ free(dev);
+ return NULL;
+}
+
+EAPI void
+ecore_drm2_device_close(Ecore_Drm2_Device *dev)
+{
+ EINA_SAFETY_ON_NULL_RETURN(dev);
+
+ /* TODO: elput_input_shutdown */
+
+ elput_manager_close(dev->em, dev->fd);
+ elput_manager_disconnect(dev->em);
+
+ /* TODO: atomic state free */
+
+ free(dev);
+}
diff --git a/src/lib/ecore_drm2/ecore_drm2_private.h b/src/lib/ecore_drm2/ecore_drm2_private.h
index 271bb1ff99..3f336e3070 100644
--- a/src/lib/ecore_drm2/ecore_drm2_private.h
+++ b/src/lib/ecore_drm2/ecore_drm2_private.h
@@ -61,4 +61,16 @@ extern int _ecore_drm2_log_dom;
# endif
# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_drm2_log_dom, __VA_ARGS__)
+/* internal structures */
+struct _Ecore_Drm2_Device
+{
+ Elput_Manager *em;
+
+ int fd;
+};
+
+/* external drm function prototypes (for dlopen) */
+extern void *(*sym_drmModeGetResources)(int fd);
+extern void (*sym_drmModeFreeResources)(drmModeResPtr ptr);
+
#endif
diff --git a/src/lib/ecore_drm2/meson.build b/src/lib/ecore_drm2/meson.build
index 4eb9dfe912..7ebe1cda76 100644
--- a/src/lib/ecore_drm2/meson.build
+++ b/src/lib/ecore_drm2/meson.build
@@ -7,6 +7,7 @@ ecore_drm2_header_src = [
]
ecore_drm2_src = files([
+ 'ecore_drm2_device.c',
'ecore_drm2.c',
'ecore_drm2_private.h'
])
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.