devilhorns pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=9c7b6572875d5245ae69300936d1cb942bfd0498
commit 9c7b6572875d5245ae69300936d1cb942bfd0498 Author: Chris Michael <[email protected]> Date: Mon May 2 10:40:47 2016 -0400 ecore-drm2: Add API functions to work with a drm device This commit adds new API functions to find, open, and close a drm device, along with API functions to retrieve clock_id and cursor size. Signed-off-by: Chris Michael <[email protected]> --- src/Makefile_Ecore_Drm2.am | 1 + src/lib/ecore_drm2/Ecore_Drm2.h | 80 ++++++++++++++ src/lib/ecore_drm2/ecore_drm2_device.c | 184 ++++++++++++++++++++++++++++++++ src/lib/ecore_drm2/ecore_drm2_private.h | 25 +++++ 4 files changed, 290 insertions(+) diff --git a/src/Makefile_Ecore_Drm2.am b/src/Makefile_Ecore_Drm2.am index 2818b0e..59e9865 100644 --- a/src/Makefile_Ecore_Drm2.am +++ b/src/Makefile_Ecore_Drm2.am @@ -9,6 +9,7 @@ dist_installed_ecoredrm2mainheaders_DATA = \ lib/ecore_drm2/Ecore_Drm2.h lib_ecore_drm2_libecore_drm2_la_SOURCES = \ +lib/ecore_drm2/ecore_drm2_device.c \ lib/ecore_drm2/ecore_drm2.c \ lib/ecore_drm2/ecore_drm2_private.h diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h index b2bbd15..bf08be2 100644 --- a/src/lib/ecore_drm2/Ecore_Drm2.h +++ b/src/lib/ecore_drm2/Ecore_Drm2.h @@ -28,6 +28,9 @@ # ifdef EFL_BETA_API_SUPPORT +/* opaque structure to represent a drm device */ +typedef struct _Ecore_Drm2_Device Ecore_Drm2_Device; + /** * @file * @brief Ecore functions for dealing with drm, virtual terminals @@ -69,6 +72,83 @@ EAPI int ecore_drm2_init(void); */ EAPI int ecore_drm2_shutdown(void); +/** + * @defgroup Ecore_Drm2_Device_Group Drm device functions + * + * Functions that deal with finding, opening, closing, or obtaining various + * information about a drm device + */ + +/** + * Try to find a drm device on a given seat + * + * @param seat + * @param tty + * @param sync + * + * @return A newly allocated Ecore_Drm2_Device on success, NULL otherwise + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI Ecore_Drm2_Device *ecore_drm2_device_find(const char *seat, unsigned int tty, Eina_Bool sync); + +/** + * Try to open a given Ecore_Drm2_Device + * + * @param device + * + * @return A valid file descriptor if open succeeds, -1 otherwise. + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI int ecore_drm2_device_open(Ecore_Drm2_Device *device); + +/** + * Close an open Ecore_Drm2_Device + * + * @param device + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI void ecore_drm2_device_close(Ecore_Drm2_Device *device); + +/** + * Free a given Ecore_Drm2_Device + * + * @param device + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI void ecore_drm2_device_free(Ecore_Drm2_Device *device); + +/** + * Get the type of clock used by a given Ecore_Drm2_Device + * + * @param device + * + * @return The clockid_t used by this drm device + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI int ecore_drm2_device_clock_id_get(Ecore_Drm2_Device *device); + +/** + * Get the size of the cursor supported by a given Ecore_Drm2_Device + * + * @param device + * @param width + * @param height + * + * @ingroup Ecore_Drm2_Device_Group + * @since 1.18 + */ +EAPI void ecore_drm2_device_cursor_size_get(Ecore_Drm2_Device *device, int *width, int *height); + # endif #endif 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 0000000..b47028b --- /dev/null +++ b/src/lib/ecore_drm2/ecore_drm2_device.c @@ -0,0 +1,184 @@ +#include "ecore_drm2_private.h" + +#ifndef DRM_CAP_CURSOR_WIDTH +# define DRM_CAP_CURSOR_WIDTH 0x8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +# define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + +static const char * +_drm2_device_find(const char *seat) +{ + Eina_List *devs, *l; + const char *dev, *ret = NULL; + Eina_Bool found = EINA_FALSE; + Eina_Bool platform = EINA_FALSE; + + devs = eeze_udev_find_by_subsystem_sysname("drm", "card[0-9]*"); + if (!devs) return NULL; + + EINA_LIST_FOREACH(devs, l, dev) + { + 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 ((seat) && (strcmp(seat, dseat))) + goto cont; + else if (strcmp(dseat, "seat0")) + goto cont; + + dparent = eeze_udev_syspath_get_parent_filtered(dev, "pci", NULL); + if (!dparent) + { + dparent = + eeze_udev_syspath_get_parent_filtered(dev, "platform", NULL); + platform = EINA_TRUE; + } + + if (dparent) + { + if (!platform) + { + 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); + } + } + else + found = EINA_TRUE; + + eina_stringshare_del(dparent); + } + +cont: + eina_stringshare_del(dpath); + eina_stringshare_del(dseat); + if (found) break; + } + + if (!found) goto out; + + ret = eeze_udev_syspath_get_devpath(dev); + +out: + EINA_LIST_FREE(devs, dev) + eina_stringshare_del(dev); + + return ret; +} + +EAPI Ecore_Drm2_Device * +ecore_drm2_device_find(const char *seat, unsigned int tty, Eina_Bool sync) +{ + Ecore_Drm2_Device *dev; + + dev = calloc(1, sizeof(Ecore_Drm2_Device)); + if (!dev) return NULL; + + dev->em = elput_manager_connect(seat, tty, sync); + if (!dev->em) + { + ERR("Could not connect to input manager"); + goto man_err; + } + + dev->path = _drm2_device_find(seat); + if (!dev->path) + { + ERR("Could not find drm device on seat %s", seat); + goto path_err; + } + + return dev; + +path_err: + elput_manager_disconnect(dev->em); +man_err: + free(dev); + return NULL; +} + +EAPI int +ecore_drm2_device_open(Ecore_Drm2_Device *device) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(device, -1); + + device->fd = elput_manager_open(device->em, device->path, -1); + + DBG("Device Path: %s", device->path); + DBG("Device Fd: %d", device->fd); + + /* NB: Not going to enable planes if we don't support atomic */ + /* if (drmSetClientCap(device->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) */ + /* ERR("Could not set Universal Plane support: %m"); */ + + return device->fd; +} + +EAPI void +ecore_drm2_device_close(Ecore_Drm2_Device *device) +{ + EINA_SAFETY_ON_NULL_RETURN(device); + EINA_SAFETY_ON_TRUE_RETURN(device->fd < 0); + + elput_manager_close(device->em, device->fd); +} + +EAPI void +ecore_drm2_device_free(Ecore_Drm2_Device *device) +{ + EINA_SAFETY_ON_NULL_RETURN(device); + + eina_stringshare_del(device->path); + free(device); +} + +EAPI int +ecore_drm2_device_clock_id_get(Ecore_Drm2_Device *device) +{ + uint64_t caps; + int ret; + + EINA_SAFETY_ON_NULL_RETURN_VAL(device, -1); + EINA_SAFETY_ON_TRUE_RETURN_VAL((device->fd < 0), -1); + + ret = drmGetCap(device->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &caps); + if ((ret == 0) && (caps == 1)) + return CLOCK_MONOTONIC; + else + return CLOCK_REALTIME; +} + +EAPI void +ecore_drm2_device_cursor_size_get(Ecore_Drm2_Device *device, int *width, int *height) +{ + uint64_t caps; + int ret; + + EINA_SAFETY_ON_NULL_RETURN(device); + EINA_SAFETY_ON_TRUE_RETURN((device->fd < 0)); + + if (width) + { + *width = 64; + ret = drmGetCap(device->fd, DRM_CAP_CURSOR_WIDTH, &caps); + if (ret == 0) *width = caps; + } + if (height) + { + *height = 64; + ret = drmGetCap(device->fd, DRM_CAP_CURSOR_HEIGHT, &caps); + if (ret == 0) *height = caps; + } +} diff --git a/src/lib/ecore_drm2/ecore_drm2_private.h b/src/lib/ecore_drm2/ecore_drm2_private.h index 6177e8e..6b4b90f 100644 --- a/src/lib/ecore_drm2/ecore_drm2_private.h +++ b/src/lib/ecore_drm2/ecore_drm2_private.h @@ -55,4 +55,29 @@ extern int _ecore_drm2_log_dom; # endif # define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_drm2_log_dom, __VA_ARGS__) +struct _Ecore_Drm2_Device +{ + Elput_Manager *em; + + int fd; + const char *path; + + int num_crtcs; + uint32_t *crtcs; + + struct + { + uint32_t crtc, conn; + } alloc; + + struct + { + uint32_t width, height; + } min, max; + + Eeze_Udev_Watch *watch; + + Eina_List *outputs; +}; + #endif --
