forked from enlightenment/efl
Merge branch 'devs/devilhorns/ecore_drm'
Summary: Merge new 1.15 API functions for ecore_drm which will be used in the E RandR config dialog. NB: This is basically a set of API functions that are needed for working with the new e_randr2 codebase in E. This makes the dialog 'usable' in E, however there is no API yet for "applying" those settings changes. That will come shortly. @feature
This commit is contained in:
commit
ba58920fbe
|
@ -29,9 +29,9 @@
|
|||
# endif // ifdef __GNUC__
|
||||
# endif // ifdef _MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# endif
|
||||
|
||||
typedef enum _Ecore_Drm_Evdev_Capabilities
|
||||
{
|
||||
|
@ -153,8 +153,14 @@ struct _Ecore_Drm_Event_Output
|
|||
/* opaque structure to represent a drm device */
|
||||
typedef struct _Ecore_Drm_Device Ecore_Drm_Device;
|
||||
|
||||
/* opaque structure to represent a drm output mode */
|
||||
typedef struct _Ecore_Drm_Output_Mode Ecore_Drm_Output_Mode;
|
||||
/* structure to represent a drm output mode */
|
||||
typedef struct _Ecore_Drm_Output_Mode
|
||||
{
|
||||
unsigned int flags;
|
||||
int width, height;
|
||||
unsigned int refresh;
|
||||
drmModeModeInfo info;
|
||||
} Ecore_Drm_Output_Mode;
|
||||
|
||||
/* opaque structure to represent a drm output */
|
||||
typedef struct _Ecore_Drm_Output Ecore_Drm_Output;
|
||||
|
@ -708,6 +714,19 @@ EAPI Eina_Stringshare *ecore_drm_output_model_get(Ecore_Drm_Output *output);
|
|||
*/
|
||||
EAPI Eina_Stringshare *ecore_drm_output_make_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the name of Ecore_Drm_Output
|
||||
*
|
||||
* This function will give the name of Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get name for
|
||||
* @return The name. Caller should free this return.
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI char *ecore_drm_output_name_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Set the dpms level of an Ecore_Drm_Output
|
||||
*
|
||||
|
@ -761,11 +780,137 @@ EAPI void ecore_drm_device_pointer_xy_get(Ecore_Drm_Device *dev, int *x, int *y)
|
|||
*/
|
||||
EAPI const Eina_List *ecore_drm_devices_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* Get the minimum and maximum screen size range
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get screen size range from
|
||||
* @param *minw The parameter in which smallest width is stored
|
||||
* @param *minh The parameter in which smallest height is stored
|
||||
* @param *maxw The parameter in which largest width is stored
|
||||
* @param *maxh The parameter in which largest height is stored
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI void ecore_drm_screen_size_range_get(Ecore_Drm_Device *dev, int *minw, int *minh, int *maxw, int *maxh);
|
||||
|
||||
/**
|
||||
* Get if a given output is connected
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the connected status of
|
||||
*
|
||||
* @return EINA_TRUE if output is connected, EINA_FALSE otherwise
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_output_connected_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the connector type of a given Ecore_Drm_Output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the connector type of
|
||||
*
|
||||
* @return An unsigned integer representing the type of connector for this output
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI unsigned int ecore_drm_output_connector_type_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get if a given output has a backlight
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the backlight of
|
||||
*
|
||||
* @return EINA_TRUE if this output has a backlight, EINA_FALSE otherwise
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI Eina_Bool ecore_drm_output_backlight_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the edid of a given output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the backlight of
|
||||
*
|
||||
* @return A string representing the edid
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI char *ecore_drm_output_edid_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get a list of the modes supported on a given output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the modes for
|
||||
*
|
||||
* @return An Eina_List of the modes supported for this output
|
||||
*
|
||||
* @note The returned list should not be freed
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI Eina_List *ecore_drm_output_modes_get(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the output which is marked as primary
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to get the primary output from
|
||||
*
|
||||
* @return The primary Ecore_Drm_Output or NULL if no primary output is set
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI Ecore_Drm_Output *ecore_drm_output_primary_get(Ecore_Drm_Device *dev);
|
||||
|
||||
/**
|
||||
* Set a given output as primary
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to set as primary
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI void ecore_drm_output_primary_set(Ecore_Drm_Output *output);
|
||||
|
||||
/**
|
||||
* Get the size of the crtc for a given output
|
||||
*
|
||||
* @param output The Ecore_Drm_Output to get the crtc size of
|
||||
* @param *width The parameter in which width is stored
|
||||
* @param *height The parameter in which height is stored
|
||||
*
|
||||
* @ingroup Ecore_Drm_Output_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI void ecore_drm_output_crtc_size_get(Ecore_Drm_Output *output, int *width, int *height);
|
||||
|
||||
/**
|
||||
* Find an Ecore_Drm_Output which has the given name
|
||||
*
|
||||
* This function will loop all the existing outputs in Ecore_Drm_Device and
|
||||
* return an output if one exists that matches the given name.
|
||||
*
|
||||
* @param dev The Ecore_Drm_Device to search
|
||||
* @param name The Ecore_Drm_Output matching this name
|
||||
*
|
||||
* @return An Ecore_Drm_Output if one exists at these coordinates or NULL
|
||||
*
|
||||
* @ingroup Ecore_Drm_Device_Group
|
||||
* @since 1.15
|
||||
*/
|
||||
EAPI Ecore_Drm_Output *ecore_drm_device_output_name_find(Ecore_Drm_Device *dev, const char *name);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#undef EAPI
|
||||
#define EAPI
|
||||
# undef EAPI
|
||||
# define EAPI
|
||||
|
||||
#endif
|
||||
|
|
|
@ -281,6 +281,10 @@ ecore_drm_device_open(Ecore_Drm_Device *dev)
|
|||
|
||||
DBG("Opened Device %s : %d", dev->drm.name, dev->drm.fd);
|
||||
|
||||
/* set client capabilities to 'universal planes' so drm core will expose
|
||||
* the full universal plane list (including primary & cursor planes) */
|
||||
drmSetClientCap(dev->drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
|
||||
if (!drmGetCap(dev->drm.fd, DRM_CAP_TIMESTAMP_MONOTONIC, &caps))
|
||||
{
|
||||
if (caps == 1)
|
||||
|
@ -530,3 +534,30 @@ ecore_drm_device_output_find(Ecore_Drm_Device *dev, int x, int y)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_screen_size_range_get(Ecore_Drm_Device *dev, int *minw, int *minh, int *maxw, int *maxh)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(dev);
|
||||
|
||||
if (minw) *minw = dev->min_width;
|
||||
if (minh) *minh = dev->min_height;
|
||||
if (maxw) *maxw = dev->max_width;
|
||||
if (maxh) *maxh = dev->max_height;
|
||||
}
|
||||
|
||||
EAPI Ecore_Drm_Output *
|
||||
ecore_drm_device_output_name_find(Ecore_Drm_Device *dev, const char *name)
|
||||
{
|
||||
Ecore_Drm_Output *output;
|
||||
Eina_List *l;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dev, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, output)
|
||||
if ((output->name) && (!strcmp(name, output->name)))
|
||||
return output;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -160,10 +160,13 @@ _ecore_drm_output_edid_find(Ecore_Drm_Output *output, drmModeConnector *conn)
|
|||
conn->prop_values[i]);
|
||||
}
|
||||
drmModeFreeProperty(prop);
|
||||
if (blob) break;
|
||||
}
|
||||
|
||||
if (!blob) return;
|
||||
|
||||
output->edid_blob = (char *)eina_memdup(blob->data, blob->length, 1);
|
||||
|
||||
ret = _ecore_drm_output_edid_parse(output, blob->data, blob->length);
|
||||
if (!ret)
|
||||
{
|
||||
|
@ -419,6 +422,8 @@ _ecore_drm_output_create(Ecore_Drm_Device *dev, drmModeRes *res, drmModeConnecto
|
|||
output->model = eina_stringshare_add("UNKNOWN");
|
||||
output->name = eina_stringshare_add("UNKNOWN");
|
||||
|
||||
output->connected = (conn->connection == DRM_MODE_CONNECTED);
|
||||
output->conn_type = conn->connector_type;
|
||||
if (conn->connector_type < ALEN(conn_types))
|
||||
type = conn_types[conn->connector_type];
|
||||
else
|
||||
|
@ -502,6 +507,13 @@ _ecore_drm_output_create(Ecore_Drm_Device *dev, drmModeRes *res, drmModeConnecto
|
|||
|
||||
dev->outputs = eina_list_append(dev->outputs, output);
|
||||
|
||||
/* NB: 'primary' output property is not supported in HW, so we need to
|
||||
* implement it via software. As such, the First output which gets
|
||||
* listed via libdrm will be assigned 'primary' until user changes
|
||||
* it via config */
|
||||
if (eina_list_count(dev->outputs) == 1)
|
||||
output->primary = EINA_TRUE;
|
||||
|
||||
DBG("Created New Output At %d,%d", output->x, output->y);
|
||||
DBG("\tCrtc Pos: %d %d", output->crtc->x, output->crtc->y);
|
||||
DBG("\tCrtc: %d", output->crtc_id);
|
||||
|
@ -510,6 +522,7 @@ _ecore_drm_output_create(Ecore_Drm_Device *dev, drmModeRes *res, drmModeConnecto
|
|||
DBG("\tModel: %s", output->model);
|
||||
DBG("\tName: %s", output->name);
|
||||
DBG("\tCloned: %d", output->cloned);
|
||||
DBG("\tPrimary: %d", output->primary);
|
||||
|
||||
EINA_LIST_FOREACH(output->modes, l, mode)
|
||||
{
|
||||
|
@ -702,6 +715,95 @@ next:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_drm_output_planes_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
drmModePlaneRes *pres;
|
||||
unsigned int i = 0, j = 0;
|
||||
int k = 0;
|
||||
|
||||
pres = drmModeGetPlaneResources(dev->drm.fd);
|
||||
if (!pres) return;
|
||||
|
||||
for (; i < pres->count_planes; i++)
|
||||
{
|
||||
drmModePlane *plane;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
int type = -1;
|
||||
|
||||
plane = drmModeGetPlane(dev->drm.fd, pres->planes[i]);
|
||||
if (!plane) continue;
|
||||
|
||||
props = drmModeObjectGetProperties(dev->drm.fd, plane->plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
if (!props) goto free_plane;
|
||||
|
||||
DBG("Plane %u Properties:", plane->plane_id);
|
||||
|
||||
for (j = 0; type == -1 && j < props->count_props; j++)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
|
||||
prop = drmModeGetProperty(dev->drm.fd, props->props[j]);
|
||||
if (!prop) continue;
|
||||
|
||||
if (!strcmp(prop->name, "type"))
|
||||
type = props->prop_values[j];
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
DBG("\tFormats:");
|
||||
for (j = 0; j < plane->count_formats; j++)
|
||||
DBG("\t\t%4.4s", (char *)&plane->formats[j]);
|
||||
|
||||
for (j = 0; j < props->count_props; j++ )
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
|
||||
prop = drmModeGetProperty(dev->drm.fd, props->props[j]);
|
||||
if (!prop) continue;
|
||||
|
||||
DBG("\tProperty Name: %s", prop->name);
|
||||
|
||||
if (prop->flags & DRM_MODE_PROP_RANGE)
|
||||
{
|
||||
DBG("\t\tRange Property");
|
||||
for (k = 0; k < prop->count_values; k++)
|
||||
DBG("\t\t\t%"PRIu64, prop->values[k]);
|
||||
}
|
||||
if (prop->flags & DRM_MODE_PROP_ENUM)
|
||||
{
|
||||
DBG("\t\tEnum Property");
|
||||
for (k = 0; k < prop->count_enums; k++)
|
||||
DBG("\t\t\t%s=%llu", prop->enums[k].name,
|
||||
prop->enums[k].value);
|
||||
}
|
||||
if (prop->flags & DRM_MODE_PROP_BITMASK)
|
||||
{
|
||||
DBG("\t\tBitmask Property");
|
||||
for (k = 0; k < prop->count_enums; k++)
|
||||
DBG("\t\t\t%s=0x%llx", prop->enums[k].name,
|
||||
(1LL << prop->enums[k].value));
|
||||
}
|
||||
|
||||
DBG("\t\tValue: %"PRIu64, props->prop_values[j]);
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
DBG("\tCurrent Crtc: %d", plane->crtc_id);
|
||||
DBG("\tPossible Crtcs: 0x%08x", plane->possible_crtcs);
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
free_plane:
|
||||
drmModeFreePlane(plane);
|
||||
}
|
||||
|
||||
drmModeFreePlaneResources(pres);
|
||||
}
|
||||
|
||||
/* public functions */
|
||||
|
||||
/**
|
||||
|
@ -748,13 +850,19 @@ ecore_drm_outputs_create(Ecore_Drm_Device *dev)
|
|||
dev->max_width = res->max_width;
|
||||
dev->max_height = res->max_height;
|
||||
|
||||
/* DBG("Dev Size"); */
|
||||
/* DBG("\tMin Width: %u", res->min_width); */
|
||||
/* DBG("\tMin Height: %u", res->min_height); */
|
||||
/* DBG("\tMax Width: %u", res->max_width); */
|
||||
/* DBG("\tMax Height: %u", res->max_height); */
|
||||
|
||||
for (i = 0; i < res->count_connectors; i++)
|
||||
{
|
||||
/* get the connector */
|
||||
if (!(conn = drmModeGetConnector(dev->drm.fd, res->connectors[i])))
|
||||
continue;
|
||||
|
||||
if (conn->connection != DRM_MODE_CONNECTED) goto next;
|
||||
/* if (conn->connection != DRM_MODE_CONNECTED) goto next; */
|
||||
|
||||
/* create output for this connector */
|
||||
if (!(output =
|
||||
|
@ -769,6 +877,7 @@ next:
|
|||
}
|
||||
|
||||
/* TODO: Planes */
|
||||
_ecore_drm_output_planes_get(dev);
|
||||
|
||||
ret = EINA_TRUE;
|
||||
if (eina_list_count(dev->outputs) < 1)
|
||||
|
@ -1091,3 +1200,94 @@ ecore_drm_output_connector_id_get(Ecore_Drm_Output *output)
|
|||
|
||||
return output->conn_id;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_drm_output_name_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
|
||||
|
||||
return strdup(output->name);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_output_connected_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
|
||||
|
||||
return output->connected;
|
||||
}
|
||||
|
||||
EAPI unsigned int
|
||||
ecore_drm_output_connector_type_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, 0);
|
||||
|
||||
return output->conn_type;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_drm_output_backlight_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
|
||||
return (output->backlight != NULL);
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_drm_output_edid_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output->edid_blob, NULL);
|
||||
|
||||
return strdup(output->edid_blob);
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
ecore_drm_output_modes_get(Ecore_Drm_Output *output)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(output->modes, NULL);
|
||||
|
||||
return output->modes;
|
||||
}
|
||||
|
||||
EAPI Ecore_Drm_Output *
|
||||
ecore_drm_output_primary_get(Ecore_Drm_Device *dev)
|
||||
{
|
||||
Ecore_Drm_Output *ret;
|
||||
const Eina_List *l;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dev, NULL);
|
||||
|
||||
EINA_LIST_FOREACH(dev->outputs, l, ret)
|
||||
if (ret->primary) return ret;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_output_primary_set(Ecore_Drm_Output *output)
|
||||
{
|
||||
const Eina_List *l;
|
||||
Ecore_Drm_Output *out;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(output);
|
||||
|
||||
/* unmark all outputs as primary */
|
||||
EINA_LIST_FOREACH(output->dev->outputs, l, out)
|
||||
out->primary = EINA_FALSE;
|
||||
|
||||
/* mark this output as primary */
|
||||
output->primary = EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_drm_output_crtc_size_get(Ecore_Drm_Output *output, int *width, int *height)
|
||||
{
|
||||
if (width) *width = 0;
|
||||
if (height) *height = 0;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(output);
|
||||
|
||||
if (width) *width = output->crtc->width;
|
||||
if (height) *height = output->crtc->height;
|
||||
}
|
||||
|
|
|
@ -87,14 +87,6 @@ typedef struct _Ecore_Drm_Pageflip_Callback
|
|||
int count;
|
||||
} Ecore_Drm_Pageflip_Callback;
|
||||
|
||||
struct _Ecore_Drm_Output_Mode
|
||||
{
|
||||
unsigned int flags;
|
||||
int width, height;
|
||||
unsigned int refresh;
|
||||
drmModeModeInfo info;
|
||||
};
|
||||
|
||||
typedef enum _Ecore_Drm_Backlight_Type
|
||||
{
|
||||
ECORE_DRM_BACKLIGHT_RAW,
|
||||
|
@ -117,6 +109,7 @@ struct _Ecore_Drm_Output
|
|||
Ecore_Drm_Device *dev;
|
||||
unsigned int crtc_id;
|
||||
unsigned int conn_id;
|
||||
unsigned int conn_type;
|
||||
drmModeCrtcPtr crtc;
|
||||
drmModePropertyPtr dpms;
|
||||
|
||||
|
@ -130,6 +123,8 @@ struct _Ecore_Drm_Output
|
|||
Ecore_Drm_Output_Mode *current_mode;
|
||||
Eina_List *modes;
|
||||
|
||||
char *edid_blob;
|
||||
|
||||
struct
|
||||
{
|
||||
char eisa[13];
|
||||
|
@ -140,6 +135,8 @@ struct _Ecore_Drm_Output
|
|||
|
||||
Ecore_Drm_Backlight *backlight;
|
||||
|
||||
Eina_Bool primary : 1;
|
||||
Eina_Bool connected : 1;
|
||||
Eina_Bool enabled : 1;
|
||||
Eina_Bool cloned : 1;
|
||||
Eina_Bool need_repaint : 1;
|
||||
|
|
Loading…
Reference in New Issue