#include <xf86.h>
#include <xf86i2c.h>
#include <xf86Crtc.h>
+#include <xf86DDC.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <X11/extensions/dpms.h>
#endif
-#include "X11/Xatom.h"
-
#include "xorg_tracker.h"
+struct output_private
+{
+ drmModeConnectorPtr drm_connector;
+ drmModePropertyBlobPtr edid_blob;
+ int fd;
+ int c;
+};
+
static char *output_enum_list[] = {
"Unknown",
"VGA",
static xf86OutputStatus
output_detect(xf86OutputPtr output)
{
- drmModeConnectorPtr drm_connector = output->driver_private;
+ modesettingPtr ms = modesettingPTR(output->scrn);
+ struct output_private *priv = output->driver_private;
+ drmModeConnectorPtr drm_connector;
+ xf86OutputStatus status;
+
+ drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id);
+ if (drm_connector) {
+ drmModeFreeConnector(priv->drm_connector);
+ priv->drm_connector = drm_connector;
+ } else {
+ drm_connector = priv->drm_connector;
+ }
switch (drm_connector->connection) {
case DRM_MODE_CONNECTED:
- return XF86OutputStatusConnected;
+ status = XF86OutputStatusConnected;
+ break;
case DRM_MODE_DISCONNECTED:
- return XF86OutputStatusDisconnected;
+ status = XF86OutputStatusDisconnected;
+ break;
default:
- return XF86OutputStatusUnknown;
+ status = XF86OutputStatusUnknown;
}
+
+ return status;
}
static DisplayModePtr
output_get_modes(xf86OutputPtr output)
{
- drmModeConnectorPtr drm_connector = output->driver_private;
+ struct output_private *priv = output->driver_private;
+ drmModeConnectorPtr drm_connector = priv->drm_connector;
drmModeModeInfoPtr drm_mode = NULL;
+ drmModePropertyPtr props = NULL;
+ xf86MonPtr ddc_mon = NULL;
DisplayModePtr modes = NULL, mode = NULL;
int i;
+ for (i = 0; i < drm_connector->count_props; i++) {
+ props = drmModeGetProperty(priv->fd, drm_connector->props[i]);
+ if (!props)
+ continue;
+
+ if (!(props->flags & DRM_MODE_PROP_BLOB))
+ goto out_free;
+
+ if (!strcmp(props->name, "EDID")) {
+ if (priv->edid_blob)
+ drmModeFreePropertyBlob(priv->edid_blob);
+ priv->edid_blob = drmModeGetPropertyBlob(priv->fd,
+ drm_connector->prop_values[i]);
+ }
+
+ out_free:
+ drmModeFreeProperty(props);
+ }
+
+ if (priv->edid_blob) {
+ ddc_mon = xf86InterpretEDID(output->scrn->scrnIndex,
+ priv->edid_blob->data);
+
+ if (ddc_mon && priv->edid_blob->length > 128)
+ ddc_mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
+ }
+ xf86OutputSetEDID(output, ddc_mon);
+
for (i = 0; i < drm_connector->count_modes; i++) {
drm_mode = &drm_connector->modes[i];
if (drm_mode) {
- mode = xcalloc(1, sizeof(DisplayModeRec));
+ mode = calloc(1, sizeof(DisplayModeRec));
if (!mode)
continue;
mode->Clock = drm_mode->clock;
static int
output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
+ modesettingPtr ms = modesettingPTR(output->scrn);
+ CustomizerPtr cust = ms->cust;
+
+ if (cust && cust->winsys_check_fb_size &&
+ !cust->winsys_check_fb_size(cust, pMode->HDisplay *
+ output->scrn->bitsPerPixel / 8,
+ pMode->VDisplay))
+ return MODE_BAD;
+
return MODE_OK;
}
static void
output_destroy(xf86OutputPtr output)
{
- drmModeFreeConnector(output->driver_private);
+ struct output_private *priv = output->driver_private;
+ if (priv->edid_blob)
+ drmModeFreePropertyBlob(priv->edid_blob);
+ drmModeFreeConnector(priv->drm_connector);
+ free(priv);
+ output->driver_private = NULL;
}
static const xf86OutputFuncsRec output_funcs = {
drmModeResPtr res;
drmModeConnectorPtr drm_connector = NULL;
drmModeEncoderPtr drm_encoder = NULL;
+ struct output_private *priv;
char name[32];
int c, v, p;
drm_connector->connector_type_id);
+ priv = calloc(sizeof(*priv), 1);
+ if (!priv) {
+ continue;
+ }
+
output = xf86OutputCreate(pScrn, &output_funcs, name);
- if (!output)
+ if (!output) {
+ free(priv);
continue;
+ }
drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
if (drm_encoder) {
output->possible_crtcs = 0;
output->possible_clones = 0;
}
- output->driver_private = drm_connector;
+ priv->c = c;
+ priv->drm_connector = drm_connector;
+ priv->fd = ms->fd;
+ output->driver_private = priv;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
drmModeFreeResources(res);
}
+unsigned
+xorg_output_get_id(xf86OutputPtr output)
+{
+ struct output_private *priv = output->driver_private;
+ return priv->drm_connector->connector_id;
+}
+
/* vim: set sw=4 ts=8 sts=4: */