summaryrefslogtreecommitdiff
path: root/src/common_drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common_drm.c')
-rw-r--r--src/common_drm.c90
1 files changed, 87 insertions, 3 deletions
diff --git a/src/common_drm.c b/src/common_drm.c
index b92b71c..e2468eb 100644
--- a/src/common_drm.c
+++ b/src/common_drm.c
@@ -1277,12 +1277,16 @@ Bool common_drm_EnterVT(VT_FUNC_ARGS_DECL)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
- if (drmSetMaster(drm->fd))
+ if (!common_drm_get_master(drm->dev)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"[drm] set master failed: %s\n", strerror(errno));
+ return FALSE;
+ }
- if (!xf86SetDesiredModes(pScrn))
+ if (!xf86SetDesiredModes(pScrn)) {
+ common_drm_put_master(drm->dev);
return FALSE;
+ }
/* Disable unused CRTCs */
for (i = 0; i < xf86_config->num_crtc; i++) {
@@ -1306,7 +1310,7 @@ void common_drm_LeaveVT(VT_FUNC_ARGS_DECL)
xf86_hide_cursors(pScrn);
- drmDropMaster(drm->fd);
+ common_drm_put_master(drm->dev);
}
void common_drm_FreeScreen(FREE_SCREEN_ARGS_DECL)
@@ -1475,3 +1479,83 @@ int common_drm_vblank_wait(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
return ret;
}
+
+
+static int common_entity_key = -1;
+
+struct common_drm_device *common_entity_get_dev(int entity_num)
+{
+ if (common_entity_key == -1)
+ common_entity_key = xf86AllocateEntityPrivateIndex();
+ if (common_entity_key == -1)
+ return NULL;
+
+ return xf86GetEntityPrivate(entity_num, common_entity_key)->ptr;
+}
+
+static void common_entity_set_dev(int entity_num, struct common_drm_device *dev)
+{
+ if (common_entity_key == -1)
+ common_entity_key = xf86AllocateEntityPrivateIndex();
+
+ xf86GetEntityPrivate(entity_num, common_entity_key)->ptr = dev;
+}
+
+struct common_drm_device *common_alloc_dev(int entity_num, int fd,
+ const char *path, Bool ddx_managed_master)
+{
+ struct common_drm_device *drm_dev;
+
+ drm_dev = malloc(sizeof *drm_dev);
+ if (!drm_dev)
+ return NULL;
+
+ drm_dev->fd = fd;
+ drm_dev->master_count = !ddx_managed_master;
+
+ if (path) {
+ drm_dev->kms_path = strdup(path);
+ if (!drm_dev->kms_path) {
+ free(drm_dev);
+ return NULL;
+ }
+ } else {
+ drm_dev->kms_path = NULL;
+ }
+
+ common_entity_set_dev(entity_num, drm_dev);
+
+ return drm_dev;
+}
+
+/*
+ * Check that what we opened was a master or a master-capable FD
+ * by setting the version of the interface we'll use to talk to it.
+ */
+Bool common_drm_fd_is_master(int fd)
+{
+ drmSetVersion sv;
+
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1;
+ sv.drm_dd_minor = -1;
+
+ return drmSetInterfaceVersion(fd, &sv) == 0;
+}
+
+Bool common_drm_get_master(struct common_drm_device *drm_dev)
+{
+ if (drm_dev->master_count++)
+ return TRUE;
+
+ return drmSetMaster(drm_dev->fd) ? FALSE : TRUE;
+}
+
+void common_drm_put_master(struct common_drm_device *drm_dev)
+{
+ assert(drm_dev->master_count);
+
+ if (--drm_dev->master_count == 0)
+ drmDropMaster(drm_dev->fd);
+}