aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/os-support
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-03-24 21:12:32 +0100
committermarha <marha@users.sourceforge.net>2014-03-24 21:12:32 +0100
commite0927d908a12c9c140458c355b29b884a7705f2d (patch)
tree360dbbd5a318ff84a951e4ca96df38393bc9783f /xorg-server/hw/xfree86/os-support
parent41fea4472dec859ddec76bdfa7108ebec71de1e3 (diff)
downloadvcxsrv-e0927d908a12c9c140458c355b29b884a7705f2d.tar.gz
vcxsrv-e0927d908a12c9c140458c355b29b884a7705f2d.tar.bz2
vcxsrv-e0927d908a12c9c140458c355b29b884a7705f2d.zip
fontconfig libxcb mesa xserver git update 24 Mar 2014
xserver commit bf087659f0fb747c471e26c5b287c35877818040 libxcb commit e2813e1cde893f384fa620ff3c13493beebabe0c fontconfig commit 9260b7ec39c34ce68d74e16d47917290a8c3f35a mesa commit 0d99aef6c8a940e52afcbffa7091ff9c854ba120
Diffstat (limited to 'xorg-server/hw/xfree86/os-support')
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_platform.c5
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/systemd-logind.c90
2 files changed, 67 insertions, 28 deletions
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
index 109a9a774..dbd7aa0aa 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
@@ -40,10 +40,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
systemd_logind_release_fd(major, minor);
return FALSE;
}
- if (!config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd)) {
- systemd_logind_release_fd(major, minor);
- return FALSE;
- }
+ config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd);
server_fd = TRUE;
}
diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
index a8406d8be..62858b062 100644
--- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
@@ -51,11 +51,43 @@ struct systemd_logind_info {
static struct systemd_logind_info logind_info;
+static InputInfoPtr
+systemd_logind_find_info_ptr_by_devnum(InputInfoPtr start,
+ int major, int minor)
+{
+ InputInfoPtr pInfo;
+
+ for (pInfo = start; pInfo; pInfo = pInfo->next)
+ if (pInfo->major == major && pInfo->minor == minor &&
+ (pInfo->flags & XI86_SERVER_FD))
+ return pInfo;
+
+ return NULL;
+}
+
+static void
+systemd_logind_set_input_fd_for_all_devs(int major, int minor, int fd,
+ Bool enable)
+{
+ InputInfoPtr pInfo;
+
+ pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor);
+ while (pInfo) {
+ pInfo->fd = fd;
+ pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
+ if (enable)
+ xf86EnableInputDeviceForVTSwitch(pInfo);
+
+ pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor);
+ }
+}
+
int
systemd_logind_take_fd(int _major, int _minor, const char *path,
Bool *paused_ret)
{
struct systemd_logind_info *info = &logind_info;
+ InputInfoPtr pInfo;
DBusError error;
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -71,6 +103,16 @@ systemd_logind_take_fd(int _major, int _minor, const char *path,
if (strstr(path, "mouse"))
return -1;
+ /* Check if we already have an InputInfo entry with this major, minor
+ * (shared device-nodes happen ie with Wacom tablets). */
+ pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor);
+ if (pInfo) {
+ LogMessage(X_INFO, "systemd-logind: returning pre-existing fd for %s %u:%u\n",
+ path, major, minor);
+ *paused_ret = FALSE;
+ return pInfo->fd;
+ }
+
dbus_error_init(&error);
msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
@@ -123,15 +165,31 @@ void
systemd_logind_release_fd(int _major, int _minor)
{
struct systemd_logind_info *info = &logind_info;
+ InputInfoPtr pInfo;
DBusError error;
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
dbus_int32_t major = _major;
dbus_int32_t minor = _minor;
+ int matches = 0;
if (!info->session || major == 0)
return;
+ /* Only release the fd if there is only 1 InputInfo left for this major
+ * and minor, otherwise other InputInfo's are still referencing the fd. */
+ pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor);
+ while (pInfo) {
+ matches++;
+ pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor);
+ }
+ if (matches > 1) {
+ LogMessage(X_INFO, "systemd-logind: not releasing fd for %u:%u, still in use\n", major, minor);
+ return;
+ }
+
+ LogMessage(X_INFO, "systemd-logind: releasing fd for %u:%u\n", major, minor);
+
dbus_error_init(&error);
msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
@@ -203,19 +261,6 @@ systemd_logind_vtenter(void)
xf86InputEnableVTProbe();
}
-static InputInfoPtr
-systemd_logind_find_info_ptr_by_devnum(int major, int minor)
-{
- InputInfoPtr pInfo;
-
- for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
- if (pInfo->major == major && pInfo->minor == minor &&
- (pInfo->flags & XI86_SERVER_FD))
- return pInfo;
-
- return NULL;
-}
-
static void
systemd_logind_ack_pause(struct systemd_logind_info *info,
dbus_int32_t minor, dbus_int32_t major)
@@ -320,7 +365,8 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
pdev = xf86_find_platform_device_by_devnum(major, minor);
if (!pdev)
- pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor);
+ pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs,
+ major, minor);
if (!pdev && !pInfo) {
LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n",
major, minor);
@@ -335,8 +381,7 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
pdev->flags |= XF86_PDEV_PAUSED;
else {
close(pInfo->fd);
- pInfo->fd = -1;
- pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", -1);
+ systemd_logind_set_input_fd_for_all_devs(major, minor, -1, FALSE);
}
if (ack)
systemd_logind_ack_pause(info, major, minor);
@@ -345,15 +390,12 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
/* info->vt_active gets set by systemd_logind_vtenter() */
info->active = TRUE;
- if (pdev) {
+ if (pdev)
pdev->flags &= ~XF86_PDEV_PAUSED;
- }
- else {
- pInfo->fd = fd;
- pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
- if (info->vt_active)
- xf86EnableInputDeviceForVTSwitch(pInfo);
- }
+ else
+ systemd_logind_set_input_fd_for_all_devs(major, minor, fd,
+ info->vt_active);
+
/* Always call vtenter(), in case there are only legacy video devs */
systemd_logind_vtenter();
}