Merge remote-tracking branch 'jwrdecoede/for-keith'
This commit is contained in:
commit
1c61d38528
|
@ -27,10 +27,12 @@
|
|||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include "os.h"
|
||||
#include "inputstr.h"
|
||||
#include "hotplug.h"
|
||||
#include "config-backends.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
void
|
||||
config_pre_init(void)
|
||||
|
@ -145,30 +147,111 @@ config_odev_free_attribute_list(struct OdevAttributes *attribs)
|
|||
free(attribs);
|
||||
}
|
||||
|
||||
static struct OdevAttribute *
|
||||
config_odev_find_attribute(struct OdevAttributes *attribs, int attrib_id)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
xorg_list_for_each_entry(oa, &attribs->list, member) {
|
||||
if (oa->attrib_id == attrib_id)
|
||||
return oa;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
|
||||
const char *attrib_name)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
oa = malloc(sizeof(struct OdevAttribute));
|
||||
oa = config_odev_find_attribute(attribs, attrib);
|
||||
if (!oa)
|
||||
oa = calloc(1, sizeof(struct OdevAttribute));
|
||||
if (!oa)
|
||||
return FALSE;
|
||||
|
||||
oa->attrib_id = attrib;
|
||||
free(oa->attrib_name);
|
||||
oa->attrib_name = strdup(attrib_name);
|
||||
oa->attrib_type = ODEV_ATTRIB_STRING;
|
||||
xorg_list_append(&oa->member, &attribs->list);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib,
|
||||
int attrib_value)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
oa = config_odev_find_attribute(attribs, attrib);
|
||||
if (!oa)
|
||||
oa = calloc(1, sizeof(struct OdevAttribute));
|
||||
if (!oa)
|
||||
return FALSE;
|
||||
|
||||
oa->attrib_id = attrib;
|
||||
oa->attrib_value = attrib_value;
|
||||
oa->attrib_type = ODEV_ATTRIB_INT;
|
||||
xorg_list_append(&oa->member, &attribs->list);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
oa = config_odev_find_attribute(attribs, attrib_id);
|
||||
if (!oa)
|
||||
return NULL;
|
||||
|
||||
if (oa->attrib_type != ODEV_ATTRIB_STRING) {
|
||||
LogMessage(X_ERROR, "Error %s called for non string attrib %d\n",
|
||||
__func__, attrib_id);
|
||||
return NULL;
|
||||
}
|
||||
return oa->attrib_name;
|
||||
}
|
||||
|
||||
int
|
||||
config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib_id, int def)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
oa = config_odev_find_attribute(attribs, attrib_id);
|
||||
if (!oa)
|
||||
return def;
|
||||
|
||||
if (oa->attrib_type != ODEV_ATTRIB_INT) {
|
||||
LogMessage(X_ERROR, "Error %s called for non integer attrib %d\n",
|
||||
__func__, attrib_id);
|
||||
return def;
|
||||
}
|
||||
|
||||
return oa->attrib_value;
|
||||
}
|
||||
|
||||
void
|
||||
config_odev_free_attributes(struct OdevAttributes *attribs)
|
||||
{
|
||||
struct OdevAttribute *iter, *safe;
|
||||
int major = 0, minor = 0, fd = -1;
|
||||
|
||||
xorg_list_for_each_entry_safe(iter, safe, &attribs->list, member) {
|
||||
switch (iter->attrib_id) {
|
||||
case ODEV_ATTRIB_MAJOR: major = iter->attrib_value; break;
|
||||
case ODEV_ATTRIB_MINOR: minor = iter->attrib_value; break;
|
||||
case ODEV_ATTRIB_FD: fd = iter->attrib_value; break;
|
||||
}
|
||||
xorg_list_del(&iter->member);
|
||||
free(iter->attrib_name);
|
||||
free(iter);
|
||||
}
|
||||
|
||||
if (fd != -1) {
|
||||
systemd_logind_release_fd(major, minor);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <libudev.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "inputstr.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "config-backends.h"
|
||||
#include "os.h"
|
||||
#include "globals.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
#define UDEV_XKB_PROP_KEY "xkb"
|
||||
|
||||
|
@ -55,9 +57,18 @@ static struct udev_monitor *udev_monitor;
|
|||
#ifdef CONFIG_UDEV_KMS
|
||||
static Bool
|
||||
config_udev_odev_setup_attribs(const char *path, const char *syspath,
|
||||
int major, int minor,
|
||||
config_odev_probe_proc_ptr probe_callback);
|
||||
#endif
|
||||
|
||||
static char itoa_buf[16];
|
||||
|
||||
static const char *itoa(int i)
|
||||
{
|
||||
snprintf(itoa_buf, sizeof(itoa_buf), "%d", i);
|
||||
return itoa_buf;
|
||||
}
|
||||
|
||||
static void
|
||||
device_added(struct udev_device *udev_device)
|
||||
{
|
||||
|
@ -73,6 +84,7 @@ device_added(struct udev_device *udev_device)
|
|||
struct udev_device *parent;
|
||||
int rc;
|
||||
const char *dev_seat;
|
||||
dev_t devnum;
|
||||
|
||||
path = udev_device_get_devnode(udev_device);
|
||||
|
||||
|
@ -91,6 +103,8 @@ device_added(struct udev_device *udev_device)
|
|||
if (!SeatId && strcmp(dev_seat, "seat0"))
|
||||
return;
|
||||
|
||||
devnum = udev_device_get_devnum(udev_device);
|
||||
|
||||
#ifdef CONFIG_UDEV_KMS
|
||||
if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
|
||||
const char *sysname = udev_device_get_sysname(udev_device);
|
||||
|
@ -98,9 +112,14 @@ device_added(struct udev_device *udev_device)
|
|||
if (strncmp(sysname, "card", 4) != 0)
|
||||
return;
|
||||
|
||||
/* Check for devices already added through xf86platformProbe() */
|
||||
if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum)))
|
||||
return;
|
||||
|
||||
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
|
||||
|
||||
config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
|
||||
config_udev_odev_setup_attribs(path, syspath, major(devnum),
|
||||
minor(devnum), NewGPUDeviceRequest);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -153,6 +172,8 @@ device_added(struct udev_device *udev_device)
|
|||
input_options = input_option_new(input_options, "name", name);
|
||||
input_options = input_option_new(input_options, "path", path);
|
||||
input_options = input_option_new(input_options, "device", path);
|
||||
input_options = input_option_new(input_options, "major", itoa(major(devnum)));
|
||||
input_options = input_option_new(input_options, "minor", itoa(minor(devnum)));
|
||||
if (path)
|
||||
attrs.device = strdup(path);
|
||||
|
||||
|
@ -270,6 +291,7 @@ device_removed(struct udev_device *device)
|
|||
if (!strcmp(udev_device_get_subsystem(device), "drm")) {
|
||||
const char *sysname = udev_device_get_sysname(device);
|
||||
const char *path = udev_device_get_devnode(device);
|
||||
dev_t devnum = udev_device_get_devnum(device);
|
||||
|
||||
if (strncmp(sysname,"card", 4) != 0)
|
||||
return;
|
||||
|
@ -277,7 +299,10 @@ device_removed(struct udev_device *device)
|
|||
if (!path)
|
||||
return;
|
||||
|
||||
config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest);
|
||||
config_udev_odev_setup_attribs(path, syspath, major(devnum),
|
||||
minor(devnum), DeleteGPUDeviceRequest);
|
||||
/* Retry vtenter after a drm node removal */
|
||||
systemd_logind_vtenter();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -427,6 +452,7 @@ config_udev_fini(void)
|
|||
|
||||
static Bool
|
||||
config_udev_odev_setup_attribs(const char *path, const char *syspath,
|
||||
int major, int minor,
|
||||
config_odev_probe_proc_ptr probe_callback)
|
||||
{
|
||||
struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
|
||||
|
@ -443,6 +469,14 @@ config_udev_odev_setup_attribs(const char *path, const char *syspath,
|
|||
if (ret == FALSE)
|
||||
goto fail;
|
||||
|
||||
ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major);
|
||||
if (ret == FALSE)
|
||||
goto fail;
|
||||
|
||||
ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor);
|
||||
if (ret == FALSE)
|
||||
goto fail;
|
||||
|
||||
/* ownership of attribs is passed to probe layer */
|
||||
probe_callback(attribs);
|
||||
return TRUE;
|
||||
|
@ -477,6 +511,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
|
|||
struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath);
|
||||
const char *path = udev_device_get_devnode(udev_device);
|
||||
const char *sysname = udev_device_get_sysname(udev_device);
|
||||
dev_t devnum = udev_device_get_devnum(udev_device);
|
||||
|
||||
if (!path || !syspath)
|
||||
goto no_probe;
|
||||
|
@ -485,8 +520,8 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
|
|||
else if (strncmp(sysname, "card", 4) != 0)
|
||||
goto no_probe;
|
||||
|
||||
config_udev_odev_setup_attribs(path, syspath, probe_callback);
|
||||
|
||||
config_udev_odev_setup_attribs(path, syspath, major(devnum),
|
||||
minor(devnum), probe_callback);
|
||||
no_probe:
|
||||
udev_device_unref(udev_device);
|
||||
}
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids, AS_HELP_STRING([--disable-clientids], [Build Xorg
|
|||
AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
|
||||
AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
|
||||
AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
|
||||
AC_ARG_ENABLE(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto])
|
||||
|
||||
dnl DDXes.
|
||||
AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
|
||||
|
@ -903,6 +904,26 @@ if test "x$CONFIG_HAL" = xyes; then
|
|||
fi
|
||||
AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
|
||||
|
||||
if test "x$SYSTEMD_LOGIND" = xauto; then
|
||||
if test "x$HAVE_DBUS" = xyes -a "x$CONFIG_UDEV" = xyes ; then
|
||||
SYSTEMD_LOGIND=yes
|
||||
else
|
||||
SYSTEMD_LOGIND=no
|
||||
fi
|
||||
fi
|
||||
if test "x$SYSTEMD_LOGIND" = xyes; then
|
||||
if ! test "x$HAVE_DBUS" = xyes; then
|
||||
AC_MSG_ERROR([systemd-logind requested, but D-Bus is not installed.])
|
||||
fi
|
||||
if ! test "x$CONFIG_UDEV" = xyes ; then
|
||||
AC_MSG_ERROR([systemd-logind is only supported in combination with udev configuration.])
|
||||
fi
|
||||
|
||||
AC_DEFINE(SYSTEMD_LOGIND, 1, [Enable systemd-logind integration])
|
||||
NEED_DBUS="yes"
|
||||
fi
|
||||
AM_CONDITIONAL(SYSTEMD_LOGIND, [test "x$SYSTEMD_LOGIND" = xyes])
|
||||
|
||||
if test "x$NEED_DBUS" = xyes; then
|
||||
AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core])
|
||||
fi
|
||||
|
|
|
@ -85,6 +85,8 @@
|
|||
#endif
|
||||
|
||||
#include "xf86platformBus.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
/*
|
||||
* This is a toggling variable:
|
||||
* FALSE = No VT switching keys have been pressed last time around
|
||||
|
@ -556,8 +558,11 @@ xf86VTEnter(void)
|
|||
/* Turn screen saver off when switching back */
|
||||
dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
|
||||
|
||||
for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
|
||||
xf86EnableInputDeviceForVTSwitch(pInfo);
|
||||
/* If we use systemd-logind it will enable input devices for us */
|
||||
if (!systemd_logind_controls_session())
|
||||
for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
|
||||
xf86EnableInputDeviceForVTSwitch(pInfo);
|
||||
|
||||
for (ih = InputHandlers; ih; ih = ih->next) {
|
||||
if (ih->is_input)
|
||||
xf86EnableInputHandler(ih);
|
||||
|
@ -589,10 +594,14 @@ xf86VTSwitch(void)
|
|||
/*
|
||||
* Since all screens are currently all in the same state it is sufficient
|
||||
* check the first. This might change in future.
|
||||
*
|
||||
* VTLeave is always handled here (VT_PROCESS guarantees this is safe),
|
||||
* if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c
|
||||
* once it has resumed all drm nodes.
|
||||
*/
|
||||
if (xf86VTOwner())
|
||||
xf86VTLeave();
|
||||
else
|
||||
else if (!systemd_logind_controls_session())
|
||||
xf86VTEnter();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "site.h"
|
||||
#include "mi.h"
|
||||
#include "dbus-core.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
|
@ -458,6 +459,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
|||
DoShowOptions();
|
||||
|
||||
dbus_core_init();
|
||||
systemd_logind_init();
|
||||
|
||||
/* Do a general bus probe. This will be a PCI probe for x86 platforms */
|
||||
xf86BusProbe();
|
||||
|
@ -1062,6 +1064,7 @@ ddxGiveUp(enum ExitCode error)
|
|||
if (xorgHWOpenConsole)
|
||||
xf86CloseConsole();
|
||||
|
||||
systemd_logind_fini();
|
||||
dbus_core_fini();
|
||||
|
||||
xf86CloseLog(error);
|
||||
|
|
|
@ -80,8 +80,8 @@ typedef enum {
|
|||
* mask is 0xFFFF0000.
|
||||
*/
|
||||
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
||||
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(15, 0)
|
||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(20, 0)
|
||||
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(16, 0)
|
||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(21, 0)
|
||||
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(8, 0)
|
||||
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "mipointer.h"
|
||||
#include "extinit.h"
|
||||
#include "loaderProcs.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
#include "exevents.h" /* AddInputDevice */
|
||||
#include "exglobals.h"
|
||||
|
@ -80,6 +81,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h> /* for int64_t */
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mi.h"
|
||||
|
||||
|
@ -103,6 +105,9 @@
|
|||
static int
|
||||
xf86InputDevicePostInit(DeviceIntPtr dev);
|
||||
|
||||
static InputInfoPtr *new_input_devices;
|
||||
static int new_input_devices_count;
|
||||
|
||||
/**
|
||||
* Eval config and modify DeviceVelocityRec accordingly
|
||||
*/
|
||||
|
@ -773,6 +778,11 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
|
|||
/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
|
||||
}
|
||||
|
||||
if (pInp->flags & XI86_SERVER_FD) {
|
||||
systemd_logind_release_fd(pInp->major, pInp->minor);
|
||||
close(pInp->fd);
|
||||
}
|
||||
|
||||
free((void *) pInp->driver);
|
||||
free((void *) pInp->name);
|
||||
xf86optionListFree(pInp->options);
|
||||
|
@ -816,6 +826,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
|
|||
{
|
||||
InputDriverPtr drv = NULL;
|
||||
DeviceIntPtr dev = NULL;
|
||||
Bool paused;
|
||||
int rval;
|
||||
|
||||
/* Memory leak for every attached device if we don't
|
||||
|
@ -830,6 +841,26 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
|
|||
goto unwind;
|
||||
}
|
||||
|
||||
if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) {
|
||||
int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
|
||||
pInfo->attrs->device, &paused);
|
||||
if (fd != -1) {
|
||||
if (paused) {
|
||||
/* Put on new_input_devices list for delayed probe */
|
||||
new_input_devices = xnfrealloc(new_input_devices,
|
||||
sizeof(pInfo) * (new_input_devices_count + 1));
|
||||
new_input_devices[new_input_devices_count] = pInfo;
|
||||
new_input_devices_count++;
|
||||
systemd_logind_release_fd(pInfo->major, pInfo->minor);
|
||||
close(fd);
|
||||
return BadMatch;
|
||||
}
|
||||
pInfo->fd = fd;
|
||||
pInfo->flags |= XI86_SERVER_FD;
|
||||
pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
|
||||
}
|
||||
}
|
||||
|
||||
xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
|
||||
pInfo->name);
|
||||
|
||||
|
@ -949,6 +980,12 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
|
|||
goto unwind;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(key, "major") == 0)
|
||||
pInfo->major = atoi(value);
|
||||
|
||||
if (strcmp(key, "minor") == 0)
|
||||
pInfo->minor = atoi(value);
|
||||
}
|
||||
|
||||
nt_list_for_each_entry(option, options, list.next) {
|
||||
|
@ -1469,4 +1506,32 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type,
|
|||
QueueTouchEvents(dev, type, touchid, flags, mask);
|
||||
}
|
||||
|
||||
void
|
||||
xf86InputEnableVTProbe(void)
|
||||
{
|
||||
int i, is_auto = 0;
|
||||
InputOption *option = NULL;
|
||||
DeviceIntPtr pdev;
|
||||
|
||||
for (i = 0; i < new_input_devices_count; i++) {
|
||||
InputInfoPtr pInfo = new_input_devices[i];
|
||||
|
||||
is_auto = 0;
|
||||
nt_list_for_each_entry(option, pInfo->options, list.next) {
|
||||
const char *key = input_option_get_key(option);
|
||||
const char *value = input_option_get_value(option);
|
||||
|
||||
if (strcmp(key, "_source") == 0 &&
|
||||
(strcmp(value, "server/hal") == 0 ||
|
||||
strcmp(value, "server/udev") == 0 ||
|
||||
strcmp(value, "server/wscons") == 0))
|
||||
is_auto = 1;
|
||||
}
|
||||
xf86NewInputDevice(pInfo, &pdev,
|
||||
(!is_auto ||
|
||||
(is_auto && xf86Info.autoEnableDevices)));
|
||||
}
|
||||
new_input_devices_count = 0;
|
||||
}
|
||||
|
||||
/* end of xf86Xinput.c */
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
/* 0x08 is reserved for legacy XI86_SEND_DRAG_EVENTS, do not use for now */
|
||||
/* server-internal only */
|
||||
#define XI86_DEVICE_DISABLED 0x10 /* device was disabled before vt switch */
|
||||
#define XI86_SERVER_FD 0x20 /* fd is managed by xserver */
|
||||
|
||||
/* Input device driver capabilities */
|
||||
#define XI86_DRV_CAP_SERVER_FD 0x01
|
||||
|
||||
/* This holds the input driver entry and module information. */
|
||||
typedef struct _InputDriverRec {
|
||||
|
@ -76,6 +80,7 @@ typedef struct _InputDriverRec {
|
|||
struct _InputInfoRec * pInfo, int flags);
|
||||
void *module;
|
||||
const char **default_options;
|
||||
int capabilities;
|
||||
} InputDriverRec, *InputDriverPtr;
|
||||
|
||||
/* This is to input devices what the ScrnInfoRec is to screens. */
|
||||
|
@ -96,6 +101,8 @@ typedef struct _InputInfoRec {
|
|||
int *valuators, int first_valuator, int num_valuators);
|
||||
|
||||
int fd;
|
||||
int major;
|
||||
int minor;
|
||||
DeviceIntPtr dev;
|
||||
void *private;
|
||||
const char *type_name;
|
||||
|
@ -172,6 +179,7 @@ extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo);
|
|||
extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
|
||||
extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
|
||||
extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev);
|
||||
extern _X_EXPORT void xf86InputEnableVTProbe(void);
|
||||
|
||||
/* not exported */
|
||||
int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
|
||||
|
|
|
@ -52,10 +52,10 @@ int platformSlotClaimed;
|
|||
|
||||
int xf86_num_platform_devices;
|
||||
|
||||
static struct xf86_platform_device *xf86_platform_devices;
|
||||
struct xf86_platform_device *xf86_platform_devices;
|
||||
|
||||
int
|
||||
xf86_add_platform_device(struct OdevAttributes *attribs)
|
||||
xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned)
|
||||
{
|
||||
xf86_platform_devices = xnfrealloc(xf86_platform_devices,
|
||||
(sizeof(struct xf86_platform_device)
|
||||
|
@ -63,6 +63,8 @@ xf86_add_platform_device(struct OdevAttributes *attribs)
|
|||
|
||||
xf86_platform_devices[xf86_num_platform_devices].attribs = attribs;
|
||||
xf86_platform_devices[xf86_num_platform_devices].pdev = NULL;
|
||||
xf86_platform_devices[xf86_num_platform_devices].flags =
|
||||
unowned ? XF86_PDEV_UNOWNED : 0;
|
||||
|
||||
xf86_num_platform_devices++;
|
||||
return 0;
|
||||
|
@ -89,35 +91,55 @@ xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_name)
|
|||
return config_odev_add_attribute(device->attribs, attrib_id, attrib_name);
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value)
|
||||
{
|
||||
return config_odev_add_int_attribute(xf86_platform_devices[index].attribs, attrib_id, attrib_value);
|
||||
}
|
||||
|
||||
char *
|
||||
xf86_get_platform_attrib(int index, int attrib_id)
|
||||
{
|
||||
struct xf86_platform_device *device = &xf86_platform_devices[index];
|
||||
struct OdevAttribute *oa;
|
||||
|
||||
xorg_list_for_each_entry(oa, &device->attribs->list, member) {
|
||||
if (oa->attrib_id == attrib_id)
|
||||
return oa->attrib_name;
|
||||
}
|
||||
return NULL;
|
||||
return config_odev_get_attribute(xf86_platform_devices[index].attribs, attrib_id);
|
||||
}
|
||||
|
||||
char *
|
||||
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id)
|
||||
{
|
||||
struct OdevAttribute *oa;
|
||||
return config_odev_get_attribute(device->attribs, attrib_id);
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry(oa, &device->attribs->list, member) {
|
||||
if (oa->attrib_id == attrib_id)
|
||||
return oa->attrib_name;
|
||||
}
|
||||
return NULL;
|
||||
int
|
||||
xf86_get_platform_int_attrib(int index, int attrib_id, int def)
|
||||
{
|
||||
return config_odev_get_int_attribute(xf86_platform_devices[index].attribs, attrib_id, def);
|
||||
}
|
||||
|
||||
int
|
||||
xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def)
|
||||
{
|
||||
return config_odev_get_int_attribute(device->attribs, attrib_id, def);
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86_get_platform_device_unowned(int index)
|
||||
{
|
||||
return xf86_platform_devices[index].attribs->unowned;
|
||||
return (xf86_platform_devices[index].flags & XF86_PDEV_UNOWNED) ?
|
||||
TRUE : FALSE;
|
||||
}
|
||||
|
||||
struct xf86_platform_device *
|
||||
xf86_find_platform_device_by_devnum(int major, int minor)
|
||||
{
|
||||
int i, attr_major, attr_minor;
|
||||
|
||||
for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
attr_major = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MAJOR, 0);
|
||||
attr_minor = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MINOR, 0);
|
||||
if (attr_major == major && attr_minor == minor)
|
||||
return &xf86_platform_devices[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -524,10 +546,10 @@ void xf86platformVTProbe(void)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
if (xf86_platform_devices[i].attribs->unowned == FALSE)
|
||||
if (!(xf86_platform_devices[i].flags & XF86_PDEV_UNOWNED))
|
||||
continue;
|
||||
|
||||
xf86_platform_devices[i].attribs->unowned = FALSE;
|
||||
xf86_platform_devices[i].flags &= ~XF86_PDEV_UNOWNED;
|
||||
xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,23 +30,34 @@ struct xf86_platform_device {
|
|||
struct OdevAttributes *attribs;
|
||||
/* for PCI devices */
|
||||
struct pci_device *pdev;
|
||||
int flags;
|
||||
};
|
||||
|
||||
/* xf86_platform_device flags */
|
||||
#define XF86_PDEV_UNOWNED 0x01
|
||||
#define XF86_PDEV_SERVER_FD 0x02
|
||||
#define XF86_PDEV_PAUSED 0x04
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
int xf86platformProbe(void);
|
||||
int xf86platformProbeDev(DriverPtr drvp);
|
||||
|
||||
extern int xf86_num_platform_devices;
|
||||
extern struct xf86_platform_device *xf86_platform_devices;
|
||||
|
||||
extern char *
|
||||
xf86_get_platform_attrib(int index, int attrib_id);
|
||||
extern int
|
||||
xf86_add_platform_device(struct OdevAttributes *attribs);
|
||||
xf86_get_platform_int_attrib(int index, int attrib_id, int def);
|
||||
extern int
|
||||
xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned);
|
||||
extern int
|
||||
xf86_remove_platform_device(int dev_index);
|
||||
extern Bool
|
||||
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
|
||||
extern Bool
|
||||
xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value);
|
||||
extern Bool
|
||||
xf86_get_platform_device_unowned(int index);
|
||||
|
||||
extern int
|
||||
|
@ -56,6 +67,8 @@ xf86platformRemoveDevice(int index);
|
|||
|
||||
extern _X_EXPORT char *
|
||||
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
|
||||
extern _X_EXPORT int
|
||||
xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def);
|
||||
extern _X_EXPORT Bool
|
||||
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid);
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@ APM_SRCS = lnx_apm.c
|
|||
XORG_CFLAGS += -DHAVE_APM
|
||||
endif
|
||||
|
||||
if SYSTEMD_LOGIND
|
||||
LOGIND_SRCS = systemd-logind.c
|
||||
XORG_CFLAGS += $(DBUS_CFLAGS)
|
||||
endif
|
||||
|
||||
liblinux_la_SOURCES = lnx_init.c lnx_video.c \
|
||||
lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \
|
||||
$(srcdir)/../shared/bios_mmap.c \
|
||||
|
@ -30,6 +35,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c \
|
|||
$(srcdir)/../shared/sigio.c \
|
||||
$(ACPI_SRCS) \
|
||||
$(APM_SRCS) \
|
||||
$(LOGIND_SRCS) \
|
||||
$(PLATFORM_PCI_SUPPORT)
|
||||
|
||||
AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES)
|
||||
|
|
|
@ -79,20 +79,15 @@ switch_to(int vt, const char *from)
|
|||
void
|
||||
xf86OpenConsole(void)
|
||||
{
|
||||
int i, fd = -1, ret;
|
||||
int i, fd = -1, ret, current_vt = -1;
|
||||
struct vt_mode VT;
|
||||
struct vt_stat vts;
|
||||
struct stat st;
|
||||
MessageType from = X_PROBED;
|
||||
const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
|
||||
const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
|
||||
|
||||
if (serverGeneration == 1) {
|
||||
|
||||
/* when KeepTty check if we're run with euid==0 */
|
||||
if (KeepTty && geteuid() != 0)
|
||||
FatalError("xf86OpenConsole:"
|
||||
" Server must be suid root for option \"KeepTTY\"\n");
|
||||
|
||||
/*
|
||||
* setup the virtual terminal manager
|
||||
*/
|
||||
|
@ -132,6 +127,22 @@ xf86OpenConsole(void)
|
|||
|
||||
xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
|
||||
|
||||
/* Some of stdin / stdout / stderr maybe redirected to a file */
|
||||
for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) {
|
||||
ret = fstat(i, &st);
|
||||
if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) {
|
||||
current_vt = minor(st.st_rdev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!KeepTty && current_vt == xf86Info.vtno) {
|
||||
xf86Msg(X_PROBED,
|
||||
"controlling tty is VT number %d, auto-enabling KeepTty\n",
|
||||
current_vt);
|
||||
KeepTty = TRUE;
|
||||
}
|
||||
|
||||
if (!KeepTty) {
|
||||
pid_t ppid = getppid();
|
||||
pid_t ppgid;
|
||||
|
|
|
@ -18,16 +18,38 @@
|
|||
#include "xf86Bus.h"
|
||||
|
||||
#include "hotplug.h"
|
||||
#include "systemd-logind.h"
|
||||
|
||||
static Bool
|
||||
get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
|
||||
{
|
||||
drmSetVersion sv;
|
||||
char *buf;
|
||||
int fd;
|
||||
int major, minor, fd;
|
||||
int err = 0;
|
||||
Bool paused, server_fd = FALSE;
|
||||
|
||||
major = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MAJOR, 0);
|
||||
minor = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MINOR, 0);
|
||||
|
||||
fd = systemd_logind_take_fd(major, minor, path, &paused);
|
||||
if (fd != -1) {
|
||||
if (paused) {
|
||||
LogMessage(X_ERROR,
|
||||
"Error systemd-logind returned paused fd for drm node\n");
|
||||
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;
|
||||
}
|
||||
server_fd = TRUE;
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
fd = open(path, O_RDWR, O_CLOEXEC);
|
||||
|
||||
fd = open(path, O_RDWR, O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return FALSE;
|
||||
|
||||
|
@ -44,16 +66,20 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
|
|||
|
||||
/* for a delayed probe we've already added the device */
|
||||
if (delayed_index == -1) {
|
||||
xf86_add_platform_device(attribs);
|
||||
xf86_add_platform_device(attribs, FALSE);
|
||||
delayed_index = xf86_num_platform_devices - 1;
|
||||
}
|
||||
|
||||
if (server_fd)
|
||||
xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD;
|
||||
|
||||
buf = drmGetBusid(fd);
|
||||
xf86_add_platform_device_attrib(delayed_index,
|
||||
ODEV_ATTRIB_BUSID, buf);
|
||||
drmFreeBusid(buf);
|
||||
out:
|
||||
close(fd);
|
||||
if (!server_fd)
|
||||
close(fd);
|
||||
return (err == 0);
|
||||
}
|
||||
|
||||
|
@ -118,17 +144,11 @@ xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs)
|
|||
void
|
||||
xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
|
||||
{
|
||||
struct OdevAttribute *attrib;
|
||||
int i;
|
||||
char *path = NULL;
|
||||
Bool ret;
|
||||
|
||||
xorg_list_for_each_entry(attrib, &attribs->list, member) {
|
||||
if (attrib->attrib_id == ODEV_ATTRIB_PATH) {
|
||||
path = attrib->attrib_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
path = config_odev_get_attribute(attribs, ODEV_ATTRIB_PATH);
|
||||
if (!path)
|
||||
goto out_free;
|
||||
|
||||
|
@ -148,8 +168,7 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
|
|||
if (!xf86VTOwner()) {
|
||||
/* if we don't currently own the VT then don't probe the device,
|
||||
just mark it as unowned for later use */
|
||||
attribs->unowned = TRUE;
|
||||
xf86_add_platform_device(attribs);
|
||||
xf86_add_platform_device(attribs, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,532 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "dbus-core.h"
|
||||
#include "xf86.h"
|
||||
#include "xf86platformBus.h"
|
||||
#include "xf86Xinput.h"
|
||||
|
||||
#include "systemd-logind.h"
|
||||
|
||||
#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */
|
||||
|
||||
struct systemd_logind_info {
|
||||
DBusConnection *conn;
|
||||
char *session;
|
||||
Bool active;
|
||||
Bool vt_active;
|
||||
};
|
||||
|
||||
static struct systemd_logind_info logind_info;
|
||||
|
||||
int
|
||||
systemd_logind_take_fd(int _major, int _minor, const char *path,
|
||||
Bool *paused_ret)
|
||||
{
|
||||
struct systemd_logind_info *info = &logind_info;
|
||||
DBusError error;
|
||||
DBusMessage *msg = NULL;
|
||||
DBusMessage *reply = NULL;
|
||||
dbus_int32_t major = _major;
|
||||
dbus_int32_t minor = _minor;
|
||||
dbus_bool_t paused;
|
||||
int fd = -1;
|
||||
|
||||
if (!info->session || major == 0)
|
||||
return -1;
|
||||
|
||||
/* logind does not support mouse devs (with evdev we don't need them) */
|
||||
if (strstr(path, "mouse"))
|
||||
return -1;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
|
||||
"org.freedesktop.login1.Session", "TakeDevice");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
|
||||
DBUS_TYPE_UINT32, &minor,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply) {
|
||||
LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n",
|
||||
path, error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dbus_message_get_args(reply, &error,
|
||||
DBUS_TYPE_UNIX_FD, &fd,
|
||||
DBUS_TYPE_BOOLEAN, &paused,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: TakeDevice %s: %s\n",
|
||||
path, error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*paused_ret = paused;
|
||||
|
||||
LogMessage(X_INFO, "systemd-logind: got fd for %s %u:%u fd %d paused %d\n",
|
||||
path, major, minor, fd, paused);
|
||||
|
||||
cleanup:
|
||||
if (msg)
|
||||
dbus_message_unref(msg);
|
||||
if (reply)
|
||||
dbus_message_unref(reply);
|
||||
dbus_error_free(&error);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
systemd_logind_release_fd(int _major, int _minor)
|
||||
{
|
||||
struct systemd_logind_info *info = &logind_info;
|
||||
DBusError error;
|
||||
DBusMessage *msg = NULL;
|
||||
DBusMessage *reply = NULL;
|
||||
dbus_int32_t major = _major;
|
||||
dbus_int32_t minor = _minor;
|
||||
|
||||
if (!info->session || major == 0)
|
||||
return;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
|
||||
"org.freedesktop.login1.Session", "ReleaseDevice");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
|
||||
DBUS_TYPE_UINT32, &minor,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply)
|
||||
LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n",
|
||||
error.message);
|
||||
|
||||
cleanup:
|
||||
if (msg)
|
||||
dbus_message_unref(msg);
|
||||
if (reply)
|
||||
dbus_message_unref(reply);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
int
|
||||
systemd_logind_controls_session(void)
|
||||
{
|
||||
return logind_info.session ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
systemd_logind_vtenter(void)
|
||||
{
|
||||
struct systemd_logind_info *info = &logind_info;
|
||||
InputInfoPtr pInfo;
|
||||
int i;
|
||||
|
||||
if (!info->session)
|
||||
return; /* Not using systemd-logind */
|
||||
|
||||
if (!info->active)
|
||||
return; /* Session not active */
|
||||
|
||||
if (info->vt_active)
|
||||
return; /* Already did vtenter */
|
||||
|
||||
for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
if (xf86_platform_devices[i].flags & XF86_PDEV_PAUSED)
|
||||
break;
|
||||
}
|
||||
if (i != xf86_num_platform_devices)
|
||||
return; /* Some drm nodes are still paused wait for resume */
|
||||
|
||||
xf86VTEnter();
|
||||
info->vt_active = TRUE;
|
||||
|
||||
/* Activate any input devices which were resumed before the drm nodes */
|
||||
for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
|
||||
if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1)
|
||||
xf86EnableInputDeviceForVTSwitch(pInfo);
|
||||
|
||||
/* Do delayed input probing, this must be done after the above enabling */
|
||||
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)
|
||||
{
|
||||
DBusError error;
|
||||
DBusMessage *msg = NULL;
|
||||
DBusMessage *reply = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
|
||||
"org.freedesktop.login1.Session", "PauseDeviceComplete");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
|
||||
DBUS_TYPE_UINT32, &minor,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply)
|
||||
LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n",
|
||||
error.message);
|
||||
|
||||
cleanup:
|
||||
if (msg)
|
||||
dbus_message_unref(msg);
|
||||
if (reply)
|
||||
dbus_message_unref(reply);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_filter(DBusConnection * connection, DBusMessage * message, void *data)
|
||||
{
|
||||
struct systemd_logind_info *info = data;
|
||||
struct xf86_platform_device *pdev = NULL;
|
||||
InputInfoPtr pInfo = NULL;
|
||||
int ack = 0, pause = 0, fd = -1;
|
||||
DBusError error;
|
||||
dbus_int32_t major, minor;
|
||||
char *pause_str;
|
||||
|
||||
if (strcmp(dbus_message_get_path(message), info->session) != 0)
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
|
||||
"PauseDevice")) {
|
||||
if (!dbus_message_get_args(message, &error,
|
||||
DBUS_TYPE_UINT32, &major,
|
||||
DBUS_TYPE_UINT32, &minor,
|
||||
DBUS_TYPE_STRING, &pause_str,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: PauseDevice: %s\n",
|
||||
error.message);
|
||||
dbus_error_free(&error);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
if (strcmp(pause_str, "pause") == 0) {
|
||||
pause = 1;
|
||||
ack = 1;
|
||||
}
|
||||
else if (strcmp(pause_str, "force") == 0) {
|
||||
pause = 1;
|
||||
}
|
||||
else if (strcmp(pause_str, "gone") == 0) {
|
||||
/* Device removal is handled through udev */
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
else {
|
||||
LogMessage(X_WARNING, "systemd-logind: unknown pause type: %s\n",
|
||||
pause_str);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
}
|
||||
else if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
|
||||
"ResumeDevice")) {
|
||||
if (!dbus_message_get_args(message, &error,
|
||||
DBUS_TYPE_UINT32, &major,
|
||||
DBUS_TYPE_UINT32, &minor,
|
||||
DBUS_TYPE_UNIX_FD, &fd,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: ResumeDevice: %s\n",
|
||||
error.message);
|
||||
dbus_error_free(&error);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
} else
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
LogMessage(X_INFO, "systemd-logind: got %s for %u:%u\n",
|
||||
pause ? "pause" : "resume", major, minor);
|
||||
|
||||
pdev = xf86_find_platform_device_by_devnum(major, minor);
|
||||
if (!pdev)
|
||||
pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor);
|
||||
if (!pdev && !pInfo) {
|
||||
LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n",
|
||||
major, minor);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
if (pause) {
|
||||
/* Our VT_PROCESS usage guarantees we've already given up the vt */
|
||||
info->active = info->vt_active = FALSE;
|
||||
/* Note the actual vtleave has already been handled by xf86Events.c */
|
||||
if (pdev)
|
||||
pdev->flags |= XF86_PDEV_PAUSED;
|
||||
else {
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", -1);
|
||||
}
|
||||
if (ack)
|
||||
systemd_logind_ack_pause(info, major, minor);
|
||||
}
|
||||
else {
|
||||
/* info->vt_active gets set by systemd_logind_vtenter() */
|
||||
info->active = TRUE;
|
||||
|
||||
if (pdev) {
|
||||
pdev->flags &= ~XF86_PDEV_PAUSED;
|
||||
systemd_logind_vtenter();
|
||||
}
|
||||
else {
|
||||
pInfo->fd = fd;
|
||||
pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
|
||||
if (info->vt_active)
|
||||
xf86EnableInputDeviceForVTSwitch(pInfo);
|
||||
}
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
static void
|
||||
connect_hook(DBusConnection *connection, void *data)
|
||||
{
|
||||
struct systemd_logind_info *info = data;
|
||||
DBusError error;
|
||||
DBusMessage *msg = NULL;
|
||||
DBusMessage *reply = NULL;
|
||||
dbus_int32_t arg;
|
||||
char *session = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1",
|
||||
"/org/freedesktop/login1", "org.freedesktop.login1.Manager",
|
||||
"GetSessionByPID");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
arg = getpid();
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &arg,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(connection, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply) {
|
||||
LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
dbus_message_unref(msg);
|
||||
|
||||
if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &session,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: GetSessionByPID: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
session = XNFstrdup(session);
|
||||
|
||||
dbus_message_unref(reply);
|
||||
reply = NULL;
|
||||
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1",
|
||||
session, "org.freedesktop.login1.Session", "TakeControl");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
arg = FALSE; /* Don't forcibly take over over the session */
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(connection, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply) {
|
||||
LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* HdG: This is not useful with systemd <= 208 since the signal only
|
||||
* contains invalidated property names there, rather than property, val
|
||||
* pairs as it should. Instead we just use the first resume / pause now.
|
||||
*/
|
||||
#if 0
|
||||
snprintf(match, sizeof(match),
|
||||
"type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='%s'",
|
||||
session);
|
||||
dbus_bus_add_match(connection, match, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dbus_connection_add_filter(connection, message_filter, info, NULL)) {
|
||||
LogMessage(X_ERROR, "systemd-logind: could not add filter: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
LogMessage(X_INFO, "systemd-logind: took control of session %s\n",
|
||||
session);
|
||||
info->conn = connection;
|
||||
info->session = session;
|
||||
info->vt_active = info->active = TRUE; /* The server owns the vt during init */
|
||||
session = NULL;
|
||||
|
||||
cleanup:
|
||||
free(session);
|
||||
if (msg)
|
||||
dbus_message_unref(msg);
|
||||
if (reply)
|
||||
dbus_message_unref(reply);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
static void
|
||||
systemd_logind_release_control(struct systemd_logind_info *info)
|
||||
{
|
||||
DBusError error;
|
||||
DBusMessage *msg = NULL;
|
||||
DBusMessage *reply = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
msg = dbus_message_new_method_call("org.freedesktop.login1",
|
||||
info->session, "org.freedesktop.login1.Session", "ReleaseControl");
|
||||
if (!msg) {
|
||||
LogMessage(X_ERROR, "systemd-logind: out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
|
||||
DBUS_TIMEOUT, &error);
|
||||
if (!reply) {
|
||||
LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n",
|
||||
error.message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (msg)
|
||||
dbus_message_unref(msg);
|
||||
if (reply)
|
||||
dbus_message_unref(reply);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_hook(void *data)
|
||||
{
|
||||
struct systemd_logind_info *info = data;
|
||||
|
||||
free(info->session);
|
||||
info->session = NULL;
|
||||
info->conn = NULL;
|
||||
}
|
||||
|
||||
static struct dbus_core_hook core_hook = {
|
||||
.connect = connect_hook,
|
||||
.disconnect = disconnect_hook,
|
||||
.data = &logind_info,
|
||||
};
|
||||
|
||||
int
|
||||
systemd_logind_init(void)
|
||||
{
|
||||
return dbus_core_add_hook(&core_hook);
|
||||
}
|
||||
|
||||
void
|
||||
systemd_logind_fini(void)
|
||||
{
|
||||
if (logind_info.session)
|
||||
systemd_logind_release_control(&logind_info);
|
||||
|
||||
dbus_core_remove_hook(&core_hook);
|
||||
}
|
|
@ -124,7 +124,11 @@ xf86OpenSerial(XF86OptionPtr options)
|
|||
return -1;
|
||||
}
|
||||
|
||||
SYSCALL(fd = open(dev, O_RDWR | O_NONBLOCK));
|
||||
fd = xf86CheckIntOption(options, "fd", -1);
|
||||
|
||||
if (fd == -1)
|
||||
SYSCALL(fd = open(dev, O_RDWR | O_NONBLOCK));
|
||||
|
||||
if (fd == -1) {
|
||||
xf86Msg(X_ERROR,
|
||||
"xf86OpenSerial: Cannot open device %s\n\t%s.\n",
|
||||
|
|
|
@ -72,4 +72,5 @@ EXTRA_DIST = \
|
|||
dix-config-apple-verbatim.h \
|
||||
dixfontstubs.h eventconvert.h eventstr.h inpututils.h \
|
||||
protocol-versions.h \
|
||||
systemd-logind.h \
|
||||
xsha1.h
|
||||
|
|
|
@ -420,6 +420,9 @@
|
|||
/* Support HAL for hotplug */
|
||||
#undef CONFIG_HAL
|
||||
|
||||
/* Enable systemd-logind integration */
|
||||
#undef SYSTEMD_LOGIND 1
|
||||
|
||||
/* Have a monotonic clock from clock_gettime() */
|
||||
#undef MONOTONIC_CLOCK
|
||||
|
||||
|
|
|
@ -32,15 +32,20 @@ extern _X_EXPORT void config_pre_init(void);
|
|||
extern _X_EXPORT void config_init(void);
|
||||
extern _X_EXPORT void config_fini(void);
|
||||
|
||||
enum { ODEV_ATTRIB_STRING, ODEV_ATTRIB_INT };
|
||||
|
||||
struct OdevAttribute {
|
||||
struct xorg_list member;
|
||||
int attrib_id;
|
||||
char *attrib_name;
|
||||
union {
|
||||
char *attrib_name;
|
||||
int attrib_value;
|
||||
};
|
||||
int attrib_type;
|
||||
};
|
||||
|
||||
struct OdevAttributes {
|
||||
struct xorg_list list;
|
||||
Bool unowned;
|
||||
};
|
||||
|
||||
struct OdevAttributes *
|
||||
|
@ -53,6 +58,17 @@ Bool
|
|||
config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
|
||||
const char *attrib_name);
|
||||
|
||||
char *
|
||||
config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id);
|
||||
|
||||
Bool
|
||||
config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib,
|
||||
int attrib_value);
|
||||
|
||||
int
|
||||
config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib,
|
||||
int def);
|
||||
|
||||
void
|
||||
config_odev_free_attributes(struct OdevAttributes *attribs);
|
||||
|
||||
|
@ -62,6 +78,12 @@ config_odev_free_attributes(struct OdevAttributes *attribs);
|
|||
#define ODEV_ATTRIB_SYSPATH 2
|
||||
/* DRI-style bus id */
|
||||
#define ODEV_ATTRIB_BUSID 3
|
||||
/* Server managed FD */
|
||||
#define ODEV_ATTRIB_FD 4
|
||||
/* Major number of the device node pointed to by ODEV_ATTRIB_PATH */
|
||||
#define ODEV_ATTRIB_MAJOR 5
|
||||
/* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */
|
||||
#define ODEV_ATTRIB_MINOR 6
|
||||
|
||||
typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs);
|
||||
void config_odev_probe(config_odev_probe_proc_ptr probe_callback);
|
||||
|
@ -72,4 +94,8 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs);
|
|||
#endif
|
||||
|
||||
#define ServerIsNotSeat0() (SeatId && strcmp(SeatId, "seat0"))
|
||||
|
||||
struct xf86_platform_device *
|
||||
xf86_find_platform_device_by_devnum(int major, int minor);
|
||||
|
||||
#endif /* HOTPLUG_H */
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef SYSTEMD_LOGIND_H
|
||||
#define SYSTEMD_LOGIND_H
|
||||
|
||||
#ifdef SYSTEMD_LOGIND
|
||||
int systemd_logind_init(void);
|
||||
void systemd_logind_fini(void);
|
||||
int systemd_logind_take_fd(int major, int minor, const char *path, Bool *paus);
|
||||
void systemd_logind_release_fd(int major, int minor);
|
||||
int systemd_logind_controls_session(void);
|
||||
void systemd_logind_vtenter(void);
|
||||
#else
|
||||
#define systemd_logind_init()
|
||||
#define systemd_logind_fini()
|
||||
#define systemd_logind_take_fd(major, minor, path) -1
|
||||
#define systemd_logind_release_fd(dev)
|
||||
#define systemd_logind_controls_session() 0
|
||||
#define systemd_logind_vtenter()
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue