forked from enlightenment/enlightenment
add read-only randr iface for wl drm output module
mostly just reads stuff right out of libdrm for now. seems to display mostly as expected. no applying yet, and only connected+active monitors will display since that's all ecore-drm tracks for now try using ecore-drm, they said. it'll be easier than using libdrm, they said.
This commit is contained in:
parent
e1697892bc
commit
2894bae445
|
@ -8,6 +8,56 @@ static Ecore_Event_Handler *activate_handler;
|
||||||
static Ecore_Event_Handler *output_handler;
|
static Ecore_Event_Handler *output_handler;
|
||||||
static Eina_Bool session_state = EINA_FALSE;
|
static Eina_Bool session_state = EINA_FALSE;
|
||||||
|
|
||||||
|
#if EFL_VERSION_MINOR == 14
|
||||||
|
/* keeping this here temporarily to make the check for backlight device
|
||||||
|
* 1 line instead of 50-100
|
||||||
|
*/
|
||||||
|
struct _Ecore_Drm_Output
|
||||||
|
{
|
||||||
|
Ecore_Drm_Device *dev;
|
||||||
|
unsigned int crtc_id;
|
||||||
|
unsigned int conn_id;
|
||||||
|
drmModeCrtcPtr crtc;
|
||||||
|
drmModePropertyPtr dpms;
|
||||||
|
|
||||||
|
int x, y, phys_width, phys_height;
|
||||||
|
|
||||||
|
int pipe;
|
||||||
|
const char *make, *model, *name;
|
||||||
|
unsigned int subpixel;
|
||||||
|
uint16_t gamma;
|
||||||
|
|
||||||
|
Ecore_Drm_Output_Mode *current_mode;
|
||||||
|
Eina_List *modes;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char eisa[13];
|
||||||
|
char monitor[13];
|
||||||
|
char pnp[5];
|
||||||
|
char serial[13];
|
||||||
|
} edid;
|
||||||
|
|
||||||
|
void *backlight;
|
||||||
|
|
||||||
|
Eina_Bool enabled : 1;
|
||||||
|
Eina_Bool cloned : 1;
|
||||||
|
Eina_Bool need_repaint : 1;
|
||||||
|
Eina_Bool repaint_scheduled : 1;
|
||||||
|
Eina_Bool pending_destroy : 1;
|
||||||
|
Eina_Bool pending_flip : 1;
|
||||||
|
Eina_Bool pending_vblank : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Ecore_Drm_Output_Mode
|
||||||
|
{
|
||||||
|
unsigned int flags;
|
||||||
|
int width, height;
|
||||||
|
unsigned int refresh;
|
||||||
|
drmModeModeInfo info;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_e_mod_drm_cb_activate(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
_e_mod_drm_cb_activate(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
{
|
{
|
||||||
|
@ -76,6 +126,8 @@ _e_mod_drm_cb_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
if (!e_randr2_cfg->ignore_hotplug_events)
|
||||||
|
e_randr2_screen_refresh_queue(EINA_TRUE);
|
||||||
return ECORE_CALLBACK_PASS_ON;
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +137,171 @@ _e_mod_drm_cb_ee_resize(Ecore_Evas *ee EINA_UNUSED)
|
||||||
e_comp_canvas_update();
|
e_comp_canvas_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static E_Randr2_Mode *
|
||||||
|
_mode_get(drmModeModeInfo *info)
|
||||||
|
{
|
||||||
|
E_Randr2_Mode *mode;
|
||||||
|
uint64_t refresh;
|
||||||
|
|
||||||
|
mode = malloc(sizeof(E_Randr2_Mode));
|
||||||
|
|
||||||
|
mode->w = info->hdisplay;
|
||||||
|
mode->h = info->vdisplay;
|
||||||
|
|
||||||
|
refresh = (info->clock * 1000000LL / info->htotal + info->vtotal / 2) / info->vtotal;
|
||||||
|
if (info->flags & DRM_MODE_FLAG_INTERLACE)
|
||||||
|
refresh *= 2;
|
||||||
|
if (info->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||||
|
refresh /= 2;
|
||||||
|
if (info->vscan > 1)
|
||||||
|
refresh /= info->vscan;
|
||||||
|
|
||||||
|
mode->refresh = refresh;
|
||||||
|
mode->preferred = (info->type & DRM_MODE_TYPE_PREFERRED);
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_get_edid(Ecore_Drm_Device *dev, drmModeConnector *conn)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
drmModePropertyBlobPtr blob = NULL;
|
||||||
|
drmModePropertyPtr prop;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
for (i = 0; i < conn->count_props; i++)
|
||||||
|
{
|
||||||
|
if (!(prop = drmModeGetProperty(dev->drm.fd, conn->props[i])))
|
||||||
|
continue;
|
||||||
|
if ((prop->flags & DRM_MODE_PROP_BLOB) &&
|
||||||
|
(!strcmp(prop->name, "EDID")))
|
||||||
|
{
|
||||||
|
blob = drmModeGetPropertyBlob(dev->drm.fd,
|
||||||
|
conn->prop_values[i]);
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
}
|
||||||
|
ret = (char*)eina_memdup(blob->data, blob->length, 1);
|
||||||
|
drmModeFreePropertyBlob(blob);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static E_Randr2 *
|
||||||
|
_drm_randr_create(void)
|
||||||
|
{
|
||||||
|
Ecore_Drm_Device *dev;
|
||||||
|
const Eina_List *l;
|
||||||
|
E_Randr2 *r;
|
||||||
|
|
||||||
|
r = E_NEW(E_Randr2, 1);
|
||||||
|
EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
|
||||||
|
{
|
||||||
|
Ecore_Drm_Output *output;
|
||||||
|
const Eina_List *ll;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(dev->outputs, ll, output)
|
||||||
|
{
|
||||||
|
E_Randr2_Screen *s;
|
||||||
|
size_t n, e;
|
||||||
|
int i;
|
||||||
|
drmModeConnector *conn;
|
||||||
|
const char *conn_types[] =
|
||||||
|
{
|
||||||
|
"None", "VGA", "DVI-I", "DVI-D", "DVI-A",
|
||||||
|
"Composite", "S-Video", "LVDS", "Component", "DIN",
|
||||||
|
"DisplayPort", "HDMI-A", "HDMI-B", "TV", "eDP", "Virtual",
|
||||||
|
"DSI", "UNKNOWN"
|
||||||
|
};
|
||||||
|
E_Randr2_Connector rtype[] =
|
||||||
|
{
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_DVI,
|
||||||
|
E_RANDR2_CONNECTOR_DVI,
|
||||||
|
E_RANDR2_CONNECTOR_DVI,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_DISPLAY_PORT,
|
||||||
|
E_RANDR2_CONNECTOR_HDMI_A,
|
||||||
|
E_RANDR2_CONNECTOR_HDMI_B,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_DISPLAY_PORT,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
E_RANDR2_CONNECTOR_UNDEFINED,
|
||||||
|
};
|
||||||
|
char buf[4096];
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
|
/* FIXME: it's insane to have this code here instead of in ecore-drm. */
|
||||||
|
conn = drmModeGetConnector(dev->drm.fd, ecore_drm_output_connector_id_get(output));
|
||||||
|
if (!conn) continue;
|
||||||
|
s = E_NEW(E_Randr2_Screen, 1);
|
||||||
|
type = MIN(conn->connector_type, EINA_C_ARRAY_LENGTH(conn_types) - 1);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s-%d", conn_types[type], conn->connector_type_id);
|
||||||
|
s->info.name = strdup(buf);
|
||||||
|
s->info.edid = _get_edid(dev, conn);
|
||||||
|
n = strlen(s->info.name);
|
||||||
|
e = strlen(s->info.edid);
|
||||||
|
s->id = malloc(n + e + 2);
|
||||||
|
eina_str_join_len(s->id, n + e + 2, '/', s->info.name, n, s->info.edid, e);
|
||||||
|
s->id[n + e + 1] = 0;
|
||||||
|
s->info.connector = rtype[type];
|
||||||
|
s->info.connected = 1;
|
||||||
|
s->info.is_lid = type == DRM_MODE_CONNECTOR_LVDS;
|
||||||
|
#if EFL_VERSION_MINOR == 14
|
||||||
|
s->info.backlight = !!output->backlight;
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < conn->count_modes; i++)
|
||||||
|
{
|
||||||
|
E_Randr2_Mode *mode;
|
||||||
|
|
||||||
|
mode = _mode_get(conn->modes + i);
|
||||||
|
if (mode)
|
||||||
|
s->info.modes = eina_list_append(s->info.modes, mode);
|
||||||
|
}
|
||||||
|
ecore_drm_output_physical_size_get(output, &s->info.size.w, &s->info.size.h);
|
||||||
|
|
||||||
|
r->screens = eina_list_append(r->screens, s);
|
||||||
|
|
||||||
|
drmModeFreeConnector(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_drm_randr_available(void)
|
||||||
|
{
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_drm_randr_stub(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_drm_randr_apply(void)
|
||||||
|
{
|
||||||
|
/* TODO: what the actual fuck */
|
||||||
|
}
|
||||||
|
|
||||||
|
static E_Comp_Screen_Iface drmiface =
|
||||||
|
{
|
||||||
|
.available = _drm_randr_available,
|
||||||
|
.init = _drm_randr_stub,
|
||||||
|
.shutdown = _drm_randr_stub,
|
||||||
|
.create = _drm_randr_create,
|
||||||
|
.apply = _drm_randr_apply
|
||||||
|
};
|
||||||
|
|
||||||
EAPI void *
|
EAPI void *
|
||||||
e_modapi_init(E_Module *m)
|
e_modapi_init(E_Module *m)
|
||||||
{
|
{
|
||||||
|
@ -130,18 +347,7 @@ e_modapi_init(E_Module *m)
|
||||||
|
|
||||||
ecore_evas_callback_resize_set(e_comp->ee, _e_mod_drm_cb_ee_resize);
|
ecore_evas_callback_resize_set(e_comp->ee, _e_mod_drm_cb_ee_resize);
|
||||||
|
|
||||||
if (!e_xinerama_fake_screens_exist())
|
e_comp->screen = &drmiface;
|
||||||
{
|
|
||||||
E_Screen *screen;
|
|
||||||
|
|
||||||
screen = E_NEW(E_Screen, 1);
|
|
||||||
screen->escreen = screen->screen = 0;
|
|
||||||
screen->x = 0;
|
|
||||||
screen->y = 0;
|
|
||||||
screen->w = w;
|
|
||||||
screen->h = h;
|
|
||||||
e_xinerama_screens_set(eina_list_append(NULL, screen));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e_comp_wl_init()) return NULL;
|
if (!e_comp_wl_init()) return NULL;
|
||||||
if (!e_comp_canvas_init(w, h)) return NULL;
|
if (!e_comp_canvas_init(w, h)) return NULL;
|
||||||
|
|
Loading…
Reference in New Issue