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.

Reply via email to