Drop config directory

Not used anymore on this branch.
This commit is contained in:
Michel Dänzer 2020-10-23 19:03:49 +02:00 committed by Michel Dänzer
parent 9335ee7994
commit 23296633bb
17 changed files with 1 additions and 2506 deletions

View File

@ -72,7 +72,7 @@ cache:
- '%CYGWIN_ROOT%\home\%USERNAME%\.ccache'
build_script:
- SET PATH=%CYGWIN_ROOT%/bin
- '%CYGWIN_ROOT%/bin/bash -lc "cd $APPVEYOR_BUILD_FOLDER; meson setup --prefix=/usr -Dxv=false -Dxf86bigfont=true -Dxvfb=true -Dhal=false -Dudev=false build"'
- '%CYGWIN_ROOT%/bin/bash -lc "cd $APPVEYOR_BUILD_FOLDER; meson setup --prefix=/usr -Dxv=false -Dxf86bigfont=true -Dxvfb=true build"'
- '%CYGWIN_ROOT%/bin/bash -lc "cd $APPVEYOR_BUILD_FOLDER; meson configure build"'
- '%CYGWIN_ROOT%/bin/bash -lc "cd $APPVEYOR_BUILD_FOLDER; ninja -C build"'
- '%CYGWIN_ROOT%/bin/bash -lc "cd $APPVEYOR_BUILD_FOLDER; ccache -s"'

View File

@ -1,38 +0,0 @@
# Collection of quirks and blacklist/whitelists for specific devices.
# Accelerometer device, posts data through ABS_X/ABS_Y, making X unusable
# http://bugs.freedesktop.org/show_bug.cgi?id=22442
Section "InputClass"
Identifier "ThinkPad HDAPS accelerometer blacklist"
MatchProduct "ThinkPad HDAPS accelerometer data"
Option "Ignore" "on"
EndSection
# https://bugzilla.redhat.com/show_bug.cgi?id=523914
# Mouse does not move in PV Xen guest
# Explicitly tell evdev to not ignore the absolute axes.
Section "InputClass"
Identifier "Xen Virtual Pointer axis blacklist"
MatchProduct "Xen Virtual Pointer"
Option "IgnoreAbsoluteAxes" "off"
Option "IgnoreRelativeAxes" "off"
EndSection
# https://bugs.freedesktop.org/show_bug.cgi?id=55867
# Bug 55867 - Doesn't know how to tag XI_TRACKBALL
Section "InputClass"
Identifier "Tag trackballs as XI_TRACKBALL"
MatchProduct "trackball"
MatchDriver "evdev"
Option "TypeName" "TRACKBALL"
EndSection
# https://bugs.freedesktop.org/show_bug.cgi?id=62831
# Bug 62831 - Mionix Naos 5000 mouse detected incorrectly
Section "InputClass"
Identifier "Tag Mionix Naos 5000 mouse XI_MOUSE"
MatchProduct "La-VIEW Technology Naos 5000 Mouse"
MatchDriver "evdev"
Option "TypeName" "MOUSE"
EndSection

View File

@ -1,46 +0,0 @@
/*
* Copyright © 2006-2007 Daniel Stone
*
* 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: Daniel Stone <daniel@fooishbar.org>
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "input.h"
#include "list.h"
void remove_devices(const char *backend, const char *config_info);
BOOL device_is_duplicate(const char *config_info);
#ifdef CONFIG_UDEV
int config_udev_pre_init(void);
int config_udev_init(void);
void config_udev_fini(void);
void config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback);
#elif defined(CONFIG_HAL)
int config_hal_init(void);
void config_hal_fini(void);
#elif defined(CONFIG_WSCONS)
int config_wscons_init(void);
void config_wscons_fini(void);
#endif

View File

@ -1,151 +0,0 @@
/*
* Copyright © 2006-2007 Daniel Stone
*
* 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: Daniel Stone <daniel@fooishbar.org>
*/
#ifdef HAVE_DIX_CONFIG_H
#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)
{
#ifdef CONFIG_UDEV
if (!config_udev_pre_init())
ErrorF("[config] failed to pre-init udev\n");
#endif
}
void
config_init(void)
{
#ifdef CONFIG_UDEV
if (!config_udev_init())
ErrorF("[config] failed to initialise udev\n");
#elif defined(CONFIG_HAL)
if (!config_hal_init())
ErrorF("[config] failed to initialise HAL\n");
#elif defined(CONFIG_WSCONS)
if (!config_wscons_init())
ErrorF("[config] failed to initialise wscons\n");
#endif
}
void
config_fini(void)
{
#if defined(CONFIG_UDEV)
config_udev_fini();
#elif defined(CONFIG_HAL)
config_hal_fini();
#elif defined(CONFIG_WSCONS)
config_wscons_fini();
#endif
}
void
config_odev_probe(config_odev_probe_proc_ptr probe_callback)
{
#if defined(CONFIG_UDEV_KMS)
config_udev_odev_probe(probe_callback);
#endif
}
static void
remove_device(const char *backend, DeviceIntPtr dev)
{
/* this only gets called for devices that have already been added */
LogMessage(X_INFO, "config/%s: removing device %s\n", backend, dev->name);
/* Call PIE here so we don't try to dereference a device that's
* already been removed. */
input_lock();
ProcessInputEvents();
DeleteInputDeviceRequest(dev);
input_unlock();
}
void
remove_devices(const char *backend, const char *config_info)
{
DeviceIntPtr dev, next;
for (dev = inputInfo.devices; dev; dev = next) {
next = dev->next;
if (dev->config_info && strcmp(dev->config_info, config_info) == 0)
remove_device(backend, dev);
}
for (dev = inputInfo.off_devices; dev; dev = next) {
next = dev->next;
if (dev->config_info && strcmp(dev->config_info, config_info) == 0)
remove_device(backend, dev);
}
RemoveInputDeviceTraces(config_info);
}
BOOL
device_is_duplicate(const char *config_info)
{
DeviceIntPtr dev;
for (dev = inputInfo.devices; dev; dev = dev->next) {
if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
return TRUE;
}
for (dev = inputInfo.off_devices; dev; dev = dev->next) {
if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
return TRUE;
}
return FALSE;
}
struct OdevAttributes *
config_odev_allocate_attributes(void)
{
struct OdevAttributes *attribs =
xnfcalloc(1, sizeof (struct OdevAttributes));
attribs->fd = -1;
return attribs;
}
void
config_odev_free_attributes(struct OdevAttributes *attribs)
{
if (attribs->fd != -1)
systemd_logind_release_fd(attribs->major, attribs->minor, attribs->fd);
free(attribs->path);
free(attribs->syspath);
free(attribs->busid);
free(attribs->driver);
free(attribs);
}

View File

@ -1,40 +0,0 @@
D-BUS Configuration API v2
----------------------------
The X server will register the bus name org.x.config.displayN, and the
object /org/x/config/N, where N is the display number.
Currently only hotplugging of input devices is supported.
org.x.config.input:
org.x.config.input.version:
Returns one unsigned int32, which is the API version.
org.x.config.input.add:
Takes an argument of key/value option pairs in arrays, e.g.:
[ss][ss][ss][ss]
is the signature for four options. These options will be passed
to the input driver as with any others.
Option names beginning with _ are not allowed; they are reserved
for internal use.
Returns a number of signed int32s. Positive integers are the
device IDs of new devices; negative numbers are X error codes,
as defined in X.h. BadMatch will be returned if the options
given do not match any device. BadValue is returned for a malformed
message. (Example: 8 is new device ID 8; -8 is BadMatch.)
Notably, BadAlloc is never returned: the server internally signals
to D-BUS that the attempt failed for lack of memory.
org.x.config.input.remove:
Takes one uint32 argument, which is the device ID to remove, i.e.:
u
is the signature.
Returns one signed int32 which represents an X status as defined in
X.h. See org.x.config.input.add. Error codes are negative numbers.
org.x.config.input.listDevices:
Lists the currently active devices. No argument.
Return value is sequence of [<id> <name>] [<id> <name>] ..., i.e. [us].

View File

@ -1,238 +0,0 @@
/*
* Copyright © 2006-2007 Daniel Stone
*
* 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: Daniel Stone <daniel@fooishbar.org>
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <dbus/dbus.h>
#include <sys/select.h>
#include "dix.h"
#include "os.h"
#include "dbus-core.h"
/* How often to attempt reconnecting when we get booted off the bus. */
#define RECONNECT_DELAY (10 * 1000) /* in ms */
struct dbus_core_info {
int fd;
DBusConnection *connection;
OsTimerPtr timer;
struct dbus_core_hook *hooks;
};
static struct dbus_core_info bus_info = { .fd = -1 };
static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg);
static void
socket_handler(int fd, int ready, void *data)
{
struct dbus_core_info *info = data;
if (info->connection) {
do {
dbus_connection_read_write_dispatch(info->connection, 0);
} while (info->connection &&
dbus_connection_get_is_connected(info->connection) &&
dbus_connection_get_dispatch_status(info->connection) ==
DBUS_DISPATCH_DATA_REMAINS);
}
}
/**
* Disconnect (if we haven't already been forcefully disconnected), clean up
* after ourselves, and call all registered disconnect hooks.
*/
static void
teardown(void)
{
struct dbus_core_hook *hook;
if (bus_info.timer) {
TimerFree(bus_info.timer);
bus_info.timer = NULL;
}
/* We should really have pre-disconnect hooks and run them here, for
* completeness. But then it gets awkward, given that you can't
* guarantee that they'll be called ... */
if (bus_info.connection)
dbus_connection_unref(bus_info.connection);
if (bus_info.fd != -1)
RemoveNotifyFd(bus_info.fd);
bus_info.fd = -1;
bus_info.connection = NULL;
for (hook = bus_info.hooks; hook; hook = hook->next) {
if (hook->disconnect)
hook->disconnect(hook->data);
}
}
/**
* This is a filter, which only handles the disconnected signal, which
* doesn't go to the normal message handling function. This takes
* precedence over the message handling function, so have have to be
* careful to ignore anything we don't want to deal with here.
*/
static DBusHandlerResult
message_filter(DBusConnection * connection, DBusMessage * message, void *data)
{
/* If we get disconnected, then take everything down, and attempt to
* reconnect immediately (assuming it's just a restart). The
* connection isn't valid at this point, so throw it out immediately. */
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
DebugF("[dbus-core] disconnected from bus\n");
bus_info.connection = NULL;
teardown();
if (bus_info.timer)
TimerFree(bus_info.timer);
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
/**
* Attempt to connect to the system bus, and set a filter to deal with
* disconnection (see message_filter above).
*
* @return 1 on success, 0 on failure.
*/
static int
connect_to_bus(void)
{
DBusError error;
struct dbus_core_hook *hook;
dbus_error_init(&error);
bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (!bus_info.connection || dbus_error_is_set(&error)) {
LogMessage(X_ERROR, "dbus-core: error connecting to system bus: %s (%s)\n",
error.name, error.message);
goto err_begin;
}
/* Thankyou. Really, thankyou. */
dbus_connection_set_exit_on_disconnect(bus_info.connection, FALSE);
if (!dbus_connection_get_unix_fd(bus_info.connection, &bus_info.fd)) {
ErrorF("[dbus-core] couldn't get fd for system bus\n");
goto err_unref;
}
if (!dbus_connection_add_filter(bus_info.connection, message_filter,
&bus_info, NULL)) {
ErrorF("[dbus-core] couldn't add filter: %s (%s)\n", error.name,
error.message);
goto err_fd;
}
dbus_error_free(&error);
SetNotifyFd(bus_info.fd, socket_handler, X_NOTIFY_READ, &bus_info);
for (hook = bus_info.hooks; hook; hook = hook->next) {
if (hook->connect)
hook->connect(bus_info.connection, hook->data);
}
return 1;
err_fd:
bus_info.fd = -1;
err_unref:
dbus_connection_unref(bus_info.connection);
bus_info.connection = NULL;
err_begin:
dbus_error_free(&error);
return 0;
}
static CARD32
reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg)
{
if (connect_to_bus()) {
TimerFree(bus_info.timer);
bus_info.timer = NULL;
return 0;
}
else {
return RECONNECT_DELAY;
}
}
int
dbus_core_add_hook(struct dbus_core_hook *hook)
{
struct dbus_core_hook **prev;
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next);
hook->next = NULL;
*prev = hook;
/* If we're already connected, call the connect hook. */
if (bus_info.connection)
hook->connect(bus_info.connection, hook->data);
return 1;
}
void
dbus_core_remove_hook(struct dbus_core_hook *hook)
{
struct dbus_core_hook **prev;
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next) {
if (*prev == hook) {
*prev = hook->next;
break;
}
}
}
int
dbus_core_init(void)
{
memset(&bus_info, 0, sizeof(bus_info));
bus_info.fd = -1;
bus_info.hooks = NULL;
if (!connect_to_bus())
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
return 1;
}
void
dbus_core_fini(void)
{
teardown();
}

View File

@ -1,202 +0,0 @@
#!/usr/bin/python
#
# Convert xorg keys from hal FDIs files to xorg.conf InputClass sections.
# Modified from Martin Pitt's original fdi2mpi.py script:
# http://cgit.freedesktop.org/media-player-info/tree/tools/fdi2mpi.py
#
# (C) 2010 Dan Nicholson
# (C) 2009 Canonical Ltd.
# Author: Dan Nicholson <dbn.lists@gmail.com>
# Author: Martin Pitt <martin.pitt@ubuntu.com>
#
# 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
# fur- nished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice 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,
# FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
# NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import sys, xml.dom.minidom
# dict converting <match> tags to Match* entries
match_table = {
'info.product': 'MatchProduct',
'input.product': 'MatchProduct',
'info.vendor': 'MatchVendor',
'input.vendor': 'MatchVendor',
'info.device': 'MatchDevicePath',
'linux.device_file': 'MatchDevicePath',
'/org/freedesktop/Hal/devices/computer:system.kernel.name': 'MatchOS',
'@info.parent:pnp.id': 'MatchPnPID',
}
# dict converting info.capabilities list to Match* entries
cap_match_table = {
'input.keys': 'MatchIsKeyboard',
'input.keyboard': 'MatchIsKeyboard',
'input.keypad': 'MatchIsKeyboard',
'input.mouse': 'MatchIsPointer',
'input.joystick': 'MatchIsJoystick',
'input.tablet': 'MatchIsTablet',
'input.touchpad': 'MatchIsTouchpad',
'input.touchscreen': 'MatchIsTouchscreen',
}
def device_glob(path):
'''Convert a contains device path to a glob entry'''
if path[0] != '/':
path = '*' + path
return path + '*'
def parse_match(node):
'''Parse a <match> tag to a tuple with InputClass values'''
match = None
value = None
booltype = False
# see what type of key we have
if node.attributes.has_key('key'):
key = node.attributes['key'].nodeValue
if key in match_table:
match = match_table[key]
elif key == 'info.capabilities':
booltype = True
# bail out now if it's unrecognized
if not match and not booltype:
return (match, value)
if node.attributes.has_key('string'):
value = node.attributes['string'].nodeValue
elif node.attributes.has_key('contains'):
value = node.attributes['contains'].nodeValue
if match == 'MatchDevicePath':
value = device_glob(value)
elif booltype and value in cap_match_table:
match = cap_match_table[value]
value = 'yes'
elif node.attributes.has_key('string_outof'):
value = node.attributes['string_outof'].nodeValue.replace(';','|')
elif node.attributes.has_key('contains_outof'):
all_values = node.attributes['contains_outof'].nodeValue.split(';')
for v in all_values:
if match == 'MatchDevicePath':
v = device_glob(v)
elif match == 'MatchPnPID' and len(v) < 7:
v += '*'
if value:
value += '|' + v
else:
value = v
return (match, value)
def parse_options(node):
'''Parse the x11_* options and return InputClass entries'''
driver = ''
ignore = False
options = []
for n in node.childNodes:
if n.nodeType != xml.dom.minidom.Node.ELEMENT_NODE:
continue
tag = n.tagName
key = n.attributes['key'].nodeValue
value = ''
if n.hasChildNodes():
content_node = n.childNodes[0]
assert content_node.nodeType == xml.dom.Node.TEXT_NODE
value = content_node.nodeValue
if tag == 'match':
continue
assert tag in ('addset', 'merge', 'append', 'remove')
if tag == 'remove' and key == 'input.x11_driver':
ignore = True
elif key == 'input.x11_driver':
driver = value
elif key.startswith('input.x11_options.'):
option = key.split('.', 2)[2]
options.append((option, value))
return (driver, ignore, options)
def is_match_node(node):
'''Check if a node is a <match> element'''
return node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and \
node.tagName == 'match'
def parse_all_matches(node):
'''Parse a x11 match tag and any parents that don't supply their
own options'''
matches = []
while True:
(key, value) = parse_match(node)
if key and value:
matches.append((key, value))
# walk up to a parent match node
node = node.parentNode
if node == None or not is_match_node(node):
break
# leave if there other options at this level
children = set([n.tagName for n in node.childNodes
if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE])
if children & set(['addset', 'merge', 'append']):
break
return matches
# stupid counter to give "unique" rule names
num_sections = 1
def print_section(matches, driver, ignore, options):
'''Print a valid InputClass section to stdout'''
global num_sections
print 'Section "InputClass"'
print '\tIdentifier "Converted Class %d"' % num_sections
num_sections += 1
for m, v in matches:
print '\t%s "%s"' % (m, v)
if driver:
print '\tDriver "%s"' % driver
if ignore:
print '\tOption "Ignore" "yes"'
for o, v in options:
print '\tOption "%s" "%s"' % (o, v)
print 'EndSection'
def parse_fdi(fdi):
'''Parse x11 matches from fdi'''
# find all <match> leaf nodes
num = 0
for match_node in fdi.getElementsByTagName('match'):
children = set([n.tagName for n in match_node.childNodes
if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE])
# see if there are any options at this level
(driver, ignore, options) = parse_options(match_node)
if not driver and not ignore and not options:
continue
matches = parse_all_matches(match_node)
if num > 0:
print
print_section(matches, driver, ignore, options)
num += 1
for f in sys.argv[1:]:
parse_fdi(xml.dom.minidom.parse(f))

View File

@ -1,675 +0,0 @@
/*
* Copyright © 2007 Daniel Stone
* Copyright © 2007 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: Daniel Stone <daniel@fooishbar.org>
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <dbus/dbus.h>
#include <hal/libhal.h>
#include <string.h>
#include <sys/select.h>
#include "dbus-core.h"
#include "input.h"
#include "inputstr.h"
#include "hotplug.h"
#include "config-backends.h"
#include "os.h"
#define LIBHAL_PROP_KEY "input.x11_options."
#define LIBHAL_XKB_PROP_KEY "input.xkb."
struct config_hal_info {
DBusConnection *system_bus;
LibHalContext *hal_ctx;
};
/* Used for special handling of xkb options. */
struct xkb_options {
char *layout;
char *model;
char *rules;
char *variant;
char *options;
};
static void
device_removed(LibHalContext * ctx, const char *udi)
{
char *value;
if (asprintf(&value, "hal:%s", udi) == -1)
return;
remove_devices("hal", value);
free(value);
}
static char *
get_prop_string(LibHalContext * hal_ctx, const char *udi, const char *name)
{
char *prop, *ret;
prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL);
LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n",
name, udi, prop ? prop : "(null)");
if (prop) {
ret = strdup(prop);
libhal_free_string(prop);
}
else {
return NULL;
}
return ret;
}
static char *
get_prop_string_array(LibHalContext * hal_ctx, const char *udi,
const char *prop)
{
char **props, *ret, *str;
int i, len = 0;
props = libhal_device_get_property_strlist(hal_ctx, udi, prop, NULL);
if (props) {
for (i = 0; props[i]; i++)
len += strlen(props[i]);
ret = calloc(sizeof(char), len + i); /* i - 1 commas, 1 NULL */
if (!ret) {
libhal_free_string_array(props);
return NULL;
}
str = ret;
for (i = 0; props[i]; i++) {
strcpy(str, props[i]);
str += strlen(props[i]);
*str++ = ',';
}
*(str - 1) = '\0';
libhal_free_string_array(props);
}
else {
return NULL;
}
return ret;
}
static void
device_added(LibHalContext * hal_ctx, const char *udi)
{
char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
char *hal_tags, *parent;
InputOption *input_options = NULL;
InputAttributes attrs = { 0 };
DeviceIntPtr dev = NULL;
DBusError error;
struct xkb_options xkb_opts = { 0 };
int rc;
LibHalPropertySet *set = NULL;
LibHalPropertySetIterator set_iter;
char *psi_key = NULL, *tmp_val;
dbus_error_init(&error);
driver = get_prop_string(hal_ctx, udi, "input.x11_driver");
if (!driver) {
/* verbose, don't tell the user unless they _want_ to see it */
LogMessageVerb(X_INFO, 7,
"config/hal: no driver specified for device %s\n", udi);
goto unwind;
}
path = get_prop_string(hal_ctx, udi, "input.device");
if (!path) {
LogMessage(X_WARNING,
"config/hal: no driver or path specified for %s\n", udi);
goto unwind;
}
attrs.device = strdup(path);
name = get_prop_string(hal_ctx, udi, "info.product");
if (!name)
name = strdup("(unnamed)");
else
attrs.product = strdup(name);
attrs.vendor = get_prop_string(hal_ctx, udi, "info.vendor");
hal_tags = get_prop_string(hal_ctx, udi, "input.tags");
attrs.tags = xstrtokenize(hal_tags, ",");
free(hal_tags);
if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL))
attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL))
attrs.flags |= ATTR_POINTER;
if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL))
attrs.flags |= ATTR_JOYSTICK;
if (libhal_device_query_capability(hal_ctx, udi, "input.tablet", NULL))
attrs.flags |= ATTR_TABLET;
if (libhal_device_query_capability(hal_ctx, udi, "input.tablet_pad", NULL))
attrs.flags |= ATTR_TABLET_PAD;
if (libhal_device_query_capability(hal_ctx, udi, "input.touchpad", NULL))
attrs.flags |= ATTR_TOUCHPAD;
if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL))
attrs.flags |= ATTR_TOUCHSCREEN;
parent = get_prop_string(hal_ctx, udi, "info.parent");
if (parent) {
int usb_vendor, usb_product;
char *old_parent;
/* construct USB ID in lowercase - "0000:ffff" */
usb_vendor = libhal_device_get_property_int(hal_ctx, parent,
"usb.vendor_id", NULL);
LogMessageVerb(X_INFO, 10,
"config/hal: getting usb.vendor_id on %s "
"returned %04x\n", parent, usb_vendor);
usb_product = libhal_device_get_property_int(hal_ctx, parent,
"usb.product_id", NULL);
LogMessageVerb(X_INFO, 10,
"config/hal: getting usb.product_id on %s "
"returned %04x\n", parent, usb_product);
if (usb_vendor && usb_product)
if (asprintf(&attrs.usb_id, "%04x:%04x", usb_vendor, usb_product)
== -1)
attrs.usb_id = NULL;
attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
old_parent = parent;
while (!attrs.pnp_id &&
(parent = get_prop_string(hal_ctx, parent, "info.parent"))) {
attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
free(old_parent);
old_parent = parent;
}
free(old_parent);
}
input_options = input_option_new(NULL, "_source", "server/hal");
if (!input_options) {
LogMessage(X_ERROR,
"config/hal: couldn't allocate first key/value pair\n");
goto unwind;
}
/* most drivers use device.. not path. evdev uses both however, but the
* path version isn't documented apparently. support both for now. */
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, "driver", driver);
input_options = input_option_new(input_options, "name", name);
if (asprintf(&config_info, "hal:%s", udi) == -1) {
config_info = NULL;
LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
goto unwind;
}
/* Check for duplicate devices */
if (device_is_duplicate(config_info)) {
LogMessage(X_WARNING,
"config/hal: device %s already added. Ignoring.\n", name);
goto unwind;
}
/* ok, grab options from hal.. iterate through all properties
* and lets see if any of them are options that we can add */
set = libhal_device_get_all_properties(hal_ctx, udi, &error);
if (!set) {
LogMessage(X_ERROR,
"config/hal: couldn't get property list for %s: %s (%s)\n",
udi, error.name, error.message);
goto unwind;
}
libhal_psi_init(&set_iter, set);
while (libhal_psi_has_more(&set_iter)) {
/* we are looking for supported keys.. extract and add to options */
psi_key = libhal_psi_get_key(&set_iter);
if (psi_key) {
/* normal options first (input.x11_options.<propname>) */
if (!strncasecmp
(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY) - 1)) {
char *tmp;
/* only support strings for all values */
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
if (tmp_val) {
/* xkb needs special handling. HAL specs include
* input.xkb.xyz options, but the x11-input.fdi specifies
* input.x11_options.Xkbxyz options. By default, we use
* the former, unless the specific X11 ones are specified.
* Since we can't predict the order in which the keys
* arrive, we need to store them.
*/
if ((tmp = strcasestr(psi_key, "xkb")) && strlen(tmp) >= 4) {
if (!strcasecmp(&tmp[3], "layout")) {
free(xkb_opts.layout);
xkb_opts.layout = strdup(tmp_val);
}
else if (!strcasecmp(&tmp[3], "model")) {
free(xkb_opts.model);
xkb_opts.model = strdup(tmp_val);
}
else if (!strcasecmp(&tmp[3], "rules")) {
free(xkb_opts.rules);
xkb_opts.rules = strdup(tmp_val);
}
else if (!strcasecmp(&tmp[3], "variant")) {
free(xkb_opts.variant);
xkb_opts.variant = strdup(tmp_val);
}
else if (!strcasecmp(&tmp[3], "options")) {
free(xkb_opts.options);
xkb_opts.options = strdup(tmp_val);
}
}
else {
/* all others */
input_options =
input_option_new(input_options,
psi_key + sizeof(LIBHAL_PROP_KEY) -
1, tmp_val);
free(tmp_val);
}
}
else {
/* server 1.4 had xkb_options as strlist. */
if ((tmp = strcasestr(psi_key, "xkb")) &&
(strlen(tmp) >= 4) &&
(!strcasecmp(&tmp[3], "options")) &&
(tmp_val =
get_prop_string_array(hal_ctx, udi, psi_key))) {
free(xkb_opts.options);
xkb_opts.options = strdup(tmp_val);
}
}
}
else if (!strncasecmp
(psi_key, LIBHAL_XKB_PROP_KEY,
sizeof(LIBHAL_XKB_PROP_KEY) - 1)) {
char *tmp;
/* only support strings for all values */
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) {
tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
if (!strcasecmp(tmp, "layout")) {
if (!xkb_opts.layout)
xkb_opts.layout = strdup(tmp_val);
}
else if (!strcasecmp(tmp, "rules")) {
if (!xkb_opts.rules)
xkb_opts.rules = strdup(tmp_val);
}
else if (!strcasecmp(tmp, "variant")) {
if (!xkb_opts.variant)
xkb_opts.variant = strdup(tmp_val);
}
else if (!strcasecmp(tmp, "model")) {
if (!xkb_opts.model)
xkb_opts.model = strdup(tmp_val);
}
else if (!strcasecmp(tmp, "options")) {
if (!xkb_opts.options)
xkb_opts.options = strdup(tmp_val);
}
free(tmp_val);
}
else {
/* server 1.4 had xkb options as strlist */
tmp_val = get_prop_string_array(hal_ctx, udi, psi_key);
if (tmp_val &&
strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) {
tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
if (!strcasecmp(tmp, ".options") && (!xkb_opts.options))
xkb_opts.options = strdup(tmp_val);
}
free(tmp_val);
}
}
}
/* psi_key doesn't need to be freed */
libhal_psi_next(&set_iter);
}
/* Now add xkb options */
if (xkb_opts.layout)
input_options =
input_option_new(input_options, "xkb_layout", xkb_opts.layout);
if (xkb_opts.rules)
input_options =
input_option_new(input_options, "xkb_rules", xkb_opts.rules);
if (xkb_opts.variant)
input_options =
input_option_new(input_options, "xkb_variant", xkb_opts.variant);
if (xkb_opts.model)
input_options =
input_option_new(input_options, "xkb_model", xkb_opts.model);
if (xkb_opts.options)
input_options =
input_option_new(input_options, "xkb_options", xkb_opts.options);
input_options = input_option_new(input_options, "config_info", config_info);
/* this isn't an error, but how else do you output something that the user can see? */
LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
if ((rc = NewInputDeviceRequest(input_options, &attrs, &dev)) != Success) {
LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n",
rc);
dev = NULL;
goto unwind;
}
unwind:
if (set)
libhal_free_property_set(set);
free(path);
free(driver);
free(name);
free(config_info);
input_option_free_list(&input_options);
free(attrs.product);
free(attrs.vendor);
free(attrs.device);
free(attrs.pnp_id);
free(attrs.usb_id);
if (attrs.tags) {
char **tag = attrs.tags;
while (*tag) {
free(*tag);
tag++;
}
free(attrs.tags);
}
free(xkb_opts.layout);
free(xkb_opts.rules);
free(xkb_opts.model);
free(xkb_opts.variant);
free(xkb_opts.options);
dbus_error_free(&error);
return;
}
static void
disconnect_hook(void *data)
{
DBusError error;
struct config_hal_info *info = data;
if (info->hal_ctx) {
if (dbus_connection_get_is_connected(info->system_bus)) {
dbus_error_init(&error);
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
LogMessage(X_WARNING,
"config/hal: disconnect_hook couldn't shut down context: %s (%s)\n",
error.name, error.message);
dbus_error_free(&error);
}
libhal_ctx_free(info->hal_ctx);
}
info->hal_ctx = NULL;
info->system_bus = NULL;
}
static BOOL
connect_and_register(DBusConnection * connection, struct config_hal_info *info)
{
DBusError error;
char **devices;
int num_devices, i;
if (info->hal_ctx)
return TRUE; /* already registered, pretend we did something */
info->system_bus = connection;
dbus_error_init(&error);
info->hal_ctx = libhal_ctx_new();
if (!info->hal_ctx) {
LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n");
goto out_err;
}
if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) {
LogMessage(X_ERROR,
"config/hal: couldn't associate HAL context with bus\n");
goto out_err;
}
if (!libhal_ctx_init(info->hal_ctx, &error)) {
LogMessage(X_ERROR,
"config/hal: couldn't initialise context: %s (%s)\n",
error.name ? error.name : "unknown error",
error.message ? error.message : "null");
goto out_err;
}
if (!libhal_device_property_watch_all(info->hal_ctx, &error)) {
LogMessage(X_ERROR,
"config/hal: couldn't watch all properties: %s (%s)\n",
error.name ? error.name : "unknown error",
error.message ? error.message : "null");
goto out_ctx;
}
libhal_ctx_set_device_added(info->hal_ctx, device_added);
libhal_ctx_set_device_removed(info->hal_ctx, device_removed);
devices = libhal_find_device_by_capability(info->hal_ctx, "input",
&num_devices, &error);
/* FIXME: Get default devices if error is set. */
if (dbus_error_is_set(&error)) {
LogMessage(X_ERROR, "config/hal: couldn't find input device: %s (%s)\n",
error.name ? error.name : "unknown error",
error.message ? error.message : "null");
goto out_ctx;
}
for (i = 0; i < num_devices; i++)
device_added(info->hal_ctx, devices[i]);
libhal_free_string_array(devices);
dbus_error_free(&error);
return TRUE;
out_ctx:
dbus_error_free(&error);
if (!libhal_ctx_shutdown(info->hal_ctx, &error)) {
LogMessage(X_WARNING,
"config/hal: couldn't shut down context: %s (%s)\n",
error.name ? error.name : "unknown error",
error.message ? error.message : "null");
dbus_error_free(&error);
}
out_err:
dbus_error_free(&error);
if (info->hal_ctx) {
libhal_ctx_free(info->hal_ctx);
}
info->hal_ctx = NULL;
info->system_bus = NULL;
return FALSE;
}
/**
* Handle NewOwnerChanged signals to deal with HAL startup at X server runtime.
*
* NewOwnerChanged is send once when HAL shuts down, and once again when it
* comes back up. Message has three arguments, first is the name
* (org.freedesktop.Hal), the second one is the old owner, third one is new
* owner.
*/
static DBusHandlerResult
ownerchanged_handler(DBusConnection * connection, DBusMessage * message,
void *data)
{
int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (dbus_message_is_signal(message,
"org.freedesktop.DBus", "NameOwnerChanged")) {
DBusError error;
char *name, *old_owner, *new_owner;
dbus_error_init(&error);
dbus_message_get_args(message, &error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID);
if (dbus_error_is_set(&error)) {
ErrorF
("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n",
error.name, error.message);
}
else if (name && strcmp(name, "org.freedesktop.Hal") == 0) {
if (!old_owner || !strlen(old_owner)) {
DebugF("[config/hal] HAL startup detected.\n");
if (connect_and_register
(connection, (struct config_hal_info *) data))
dbus_connection_unregister_object_path(connection,
"/org/freedesktop/DBus");
else
ErrorF("[config/hal] Failed to connect to HAL bus.\n");
}
ret = DBUS_HANDLER_RESULT_HANDLED;
}
dbus_error_free(&error);
}
return ret;
}
/**
* Register a handler for the NameOwnerChanged signal.
*/
static BOOL
listen_for_startup(DBusConnection * connection, void *data)
{
DBusObjectPathVTable vtable = {.message_function = ownerchanged_handler, };
DBusError error;
const char MATCH_RULE[] = "sender='org.freedesktop.DBus',"
"interface='org.freedesktop.DBus',"
"type='signal',"
"path='/org/freedesktop/DBus'," "member='NameOwnerChanged'";
int rc = FALSE;
dbus_error_init(&error);
dbus_bus_add_match(connection, MATCH_RULE, &error);
if (!dbus_error_is_set(&error)) {
if (dbus_connection_register_object_path(connection,
"/org/freedesktop/DBus",
&vtable, data))
rc = TRUE;
else
ErrorF("[config/hal] cannot register object path.\n");
}
else {
ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name,
error.message);
ErrorF("[config/hal] cannot detect a HAL startup.\n");
}
dbus_error_free(&error);
return rc;
}
static void
connect_hook(DBusConnection * connection, void *data)
{
struct config_hal_info *info = data;
if (listen_for_startup(connection, data) &&
connect_and_register(connection, info))
dbus_connection_unregister_object_path(connection,
"/org/freedesktop/DBus");
return;
}
static struct config_hal_info hal_info;
static struct dbus_core_hook hook = {
.connect = connect_hook,
.disconnect = disconnect_hook,
.data = &hal_info,
};
int
config_hal_init(void)
{
memset(&hal_info, 0, sizeof(hal_info));
hal_info.system_bus = NULL;
hal_info.hal_ctx = NULL;
if (!dbus_core_add_hook(&hook)) {
LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n");
return 0;
}
/* verbose message */
LogMessageVerb(X_INFO, 7, "config/hal: initialized\n");
return 1;
}
void
config_hal_fini(void)
{
dbus_core_remove_hook(&hook);
}

View File

@ -1,24 +0,0 @@
srcs_config = [
'config.c',
]
config_dep = [common_dep]
if build_dbus
srcs_config += 'dbus-core.c'
config_dep += dbus_dep
endif
if build_hal
srcs_config += 'hal.c'
config_dep += hal_dep
endif
if build_udev
srcs_config += 'udev.c'
config_dep += udev_dep
endif
if host_machine.system() == 'openbsd'
srcs_config += 'wscons.c'
endif

View File

@ -1,579 +0,0 @@
/*
* Copyright © 2009 Julien Cristau
*
* 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: Julien Cristau <jcristau@debian.org>
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <libudev.h>
#include <ctype.h>
#include <unistd.h>
#include "input.h"
#include "inputstr.h"
#include "hotplug.h"
#include "config-backends.h"
#include "os.h"
#include "globals.h"
#include "systemd-logind.h"
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#define UDEV_XKB_PROP_KEY "xkb"
#define LOG_PROPERTY(path, prop, val) \
LogMessageVerb(X_INFO, 10, \
"config/udev: getting property %s on %s " \
"returned \"%s\"\n", \
(prop), (path), (val) ? (val) : "(null)")
#define LOG_SYSATTR(path, attr, val) \
LogMessageVerb(X_INFO, 10, \
"config/udev: getting attribute %s on %s " \
"returned \"%s\"\n", \
(attr), (path), (val) ? (val) : "(null)")
static struct udev_monitor *udev_monitor;
#ifdef CONFIG_UDEV_KMS
static void
config_udev_odev_setup_attribs(struct udev_device *udev_device, 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 Bool
check_seat(struct udev_device *udev_device)
{
const char *dev_seat;
dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
if (!dev_seat)
dev_seat = "seat0";
if (SeatId && strcmp(dev_seat, SeatId))
return FALSE;
if (!SeatId && strcmp(dev_seat, "seat0"))
return FALSE;
return TRUE;
}
static void
device_added(struct udev_device *udev_device)
{
const char *path, *name = NULL;
char *config_info = NULL;
const char *syspath;
const char *tags_prop;
const char *key, *value, *tmp;
#ifdef CONFIG_UDEV_KMS
const char *subsys = NULL;
#endif
InputOption *input_options;
InputAttributes attrs = { };
DeviceIntPtr dev = NULL;
struct udev_list_entry *set, *entry;
struct udev_device *parent;
int rc;
dev_t devnum;
path = udev_device_get_devnode(udev_device);
syspath = udev_device_get_syspath(udev_device);
if (!path || !syspath)
return;
if (!check_seat(udev_device))
return;
devnum = udev_device_get_devnum(udev_device);
#ifdef CONFIG_UDEV_KMS
subsys = udev_device_get_subsystem(udev_device);
if (subsys && !strcmp(subsys, "drm")) {
const char *sysname = udev_device_get_sysname(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(udev_device, path, syspath, major(devnum),
minor(devnum), NewGPUDeviceRequest);
return;
}
#endif
value = udev_device_get_property_value(udev_device, "ID_INPUT");
if (!value || !strcmp(value, "0")) {
LogMessageVerb(X_INFO, 10,
"config/udev: ignoring device %s without "
"property ID_INPUT set\n", path);
return;
}
input_options = input_option_new(NULL, "_source", "server/udev");
if (!input_options)
return;
parent = udev_device_get_parent(udev_device);
if (parent) {
const char *ppath = udev_device_get_devnode(parent);
const char *product = udev_device_get_property_value(parent, "PRODUCT");
const char *pnp_id = udev_device_get_sysattr_value(parent, "id");
unsigned int usb_vendor, usb_model;
name = udev_device_get_sysattr_value(parent, "name");
LOG_SYSATTR(ppath, "name", name);
if (!name) {
name = udev_device_get_property_value(parent, "NAME");
LOG_PROPERTY(ppath, "NAME", name);
}
/* construct USB ID in lowercase hex - "0000:ffff" */
if (product &&
sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) {
char *usb_id;
if (asprintf(&usb_id, "%04x:%04x", usb_vendor, usb_model)
== -1)
usb_id = NULL;
else
LOG_PROPERTY(ppath, "PRODUCT", product);
attrs.usb_id = usb_id;
}
while (!pnp_id && (parent = udev_device_get_parent(parent))) {
pnp_id = udev_device_get_sysattr_value(parent, "id");
if (!pnp_id)
continue;
attrs.pnp_id = strdup(pnp_id);
ppath = udev_device_get_devnode(parent);
LOG_SYSATTR(ppath, "id", pnp_id);
}
}
if (!name)
name = "(unnamed)";
else
attrs.product = strdup(name);
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);
tags_prop = udev_device_get_property_value(udev_device, "ID_INPUT.tags");
LOG_PROPERTY(path, "ID_INPUT.tags", tags_prop);
attrs.tags = xstrtokenize(tags_prop, ",");
if (asprintf(&config_info, "udev:%s", syspath) == -1) {
config_info = NULL;
goto unwind;
}
if (device_is_duplicate(config_info)) {
LogMessage(X_WARNING, "config/udev: device %s already added. "
"Ignoring.\n", name);
goto unwind;
}
set = udev_device_get_properties_list_entry(udev_device);
udev_list_entry_foreach(entry, set) {
key = udev_list_entry_get_name(entry);
if (!key)
continue;
value = udev_list_entry_get_value(entry);
if (!strncasecmp(key, UDEV_XKB_PROP_KEY, sizeof(UDEV_XKB_PROP_KEY) - 1)) {
LOG_PROPERTY(path, key, value);
tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1;
if (!strcasecmp(tmp, "rules"))
input_options =
input_option_new(input_options, "xkb_rules", value);
else if (!strcasecmp(tmp, "layout"))
input_options =
input_option_new(input_options, "xkb_layout", value);
else if (!strcasecmp(tmp, "variant"))
input_options =
input_option_new(input_options, "xkb_variant", value);
else if (!strcasecmp(tmp, "model"))
input_options =
input_option_new(input_options, "xkb_model", value);
else if (!strcasecmp(tmp, "options"))
input_options =
input_option_new(input_options, "xkb_options", value);
}
else if (!strcmp(key, "ID_VENDOR")) {
LOG_PROPERTY(path, key, value);
attrs.vendor = strdup(value);
} else if (!strncmp(key, "ID_INPUT_", 9)) {
const struct pfmap {
const char *property;
unsigned int flag;
} map[] = {
{ "ID_INPUT_KEY", ATTR_KEY },
{ "ID_INPUT_KEYBOARD", ATTR_KEYBOARD },
{ "ID_INPUT_MOUSE", ATTR_POINTER },
{ "ID_INPUT_JOYSTICK", ATTR_JOYSTICK },
{ "ID_INPUT_TABLET", ATTR_TABLET },
{ "ID_INPUT_TABLET_PAD", ATTR_TABLET_PAD },
{ "ID_INPUT_TOUCHPAD", ATTR_TOUCHPAD },
{ "ID_INPUT_TOUCHSCREEN", ATTR_TOUCHSCREEN },
{ NULL, 0 },
};
/* Anything but the literal string "0" is considered a
* boolean true. The empty string isn't a thing with udev
* properties anyway */
if (value && strcmp(value, "0")) {
const struct pfmap *m = map;
while (m->property != NULL) {
if (!strcmp(m->property, key)) {
LOG_PROPERTY(path, key, value);
attrs.flags |= m->flag;
}
m++;
}
}
}
}
input_options = input_option_new(input_options, "config_info", config_info);
/* Default setting needed for non-seat0 seats */
if (ServerIsNotSeat0())
input_options = input_option_new(input_options, "GrabDevice", "on");
LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
name, path);
rc = NewInputDeviceRequest(input_options, &attrs, &dev);
if (rc != Success)
goto unwind;
unwind:
free(config_info);
input_option_free_list(&input_options);
free(attrs.usb_id);
free(attrs.pnp_id);
free(attrs.product);
free(attrs.device);
free(attrs.vendor);
if (attrs.tags) {
char **tag = attrs.tags;
while (*tag) {
free(*tag);
tag++;
}
free(attrs.tags);
}
return;
}
static void
device_removed(struct udev_device *device)
{
char *value;
const char *syspath = udev_device_get_syspath(device);
#ifdef CONFIG_UDEV_KMS
const char *subsys = udev_device_get_subsystem(device);
if (subsys && !strcmp(subsys, "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) || (path == NULL))
return;
LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n",
syspath, path);
config_udev_odev_setup_attribs(device, path, syspath, major(devnum),
minor(devnum), DeleteGPUDeviceRequest);
/* Retry vtenter after a drm node removal */
systemd_logind_vtenter();
return;
}
#endif
if (asprintf(&value, "udev:%s", syspath) == -1)
return;
remove_devices("udev", value);
free(value);
}
static void
socket_handler(int fd, int ready, void *data)
{
struct udev_device *udev_device;
const char *action;
input_lock();
udev_device = udev_monitor_receive_device(udev_monitor);
if (!udev_device) {
input_unlock();
return;
}
action = udev_device_get_action(udev_device);
if (action) {
if (!strcmp(action, "add")) {
device_removed(udev_device);
device_added(udev_device);
} else if (!strcmp(action, "change")) {
/* ignore change for the drm devices */
const char *subsys = udev_device_get_subsystem(udev_device);
if (subsys && strcmp(subsys, "drm")) {
device_removed(udev_device);
device_added(udev_device);
}
}
else if (!strcmp(action, "remove"))
device_removed(udev_device);
}
udev_device_unref(udev_device);
input_unlock();
}
int
config_udev_pre_init(void)
{
struct udev *udev;
udev = udev_new();
if (!udev)
return 0;
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
if (!udev_monitor)
return 0;
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
NULL);
/* For Wacom serial devices */
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL);
#ifdef CONFIG_UDEV_KMS
/* For output GPU devices */
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "drm", NULL);
#endif
#ifdef HAVE_UDEV_MONITOR_FILTER_ADD_MATCH_TAG
if (ServerIsNotSeat0())
udev_monitor_filter_add_match_tag(udev_monitor, SeatId);
#endif
if (udev_monitor_enable_receiving(udev_monitor)) {
ErrorF("config/udev: failed to bind the udev monitor\n");
return 0;
}
return 1;
}
int
config_udev_init(void)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *device;
udev = udev_monitor_get_udev(udev_monitor);
enumerate = udev_enumerate_new(udev);
if (!enumerate)
return 0;
udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_add_match_subsystem(enumerate, "tty");
#ifdef CONFIG_UDEV_KMS
udev_enumerate_add_match_subsystem(enumerate, "drm");
#endif
#ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
if (ServerIsNotSeat0())
udev_enumerate_add_match_tag(enumerate, SeatId);
#endif
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(device, devices) {
const char *syspath = udev_list_entry_get_name(device);
struct udev_device *udev_device =
udev_device_new_from_syspath(udev, syspath);
/* Device might be gone by the time we try to open it */
if (!udev_device)
continue;
device_added(udev_device);
udev_device_unref(udev_device);
}
udev_enumerate_unref(enumerate);
SetNotifyFd(udev_monitor_get_fd(udev_monitor), socket_handler, X_NOTIFY_READ, NULL);
return 1;
}
void
config_udev_fini(void)
{
struct udev *udev;
if (!udev_monitor)
return;
udev = udev_monitor_get_udev(udev_monitor);
RemoveNotifyFd(udev_monitor_get_fd(udev_monitor));
udev_monitor_unref(udev_monitor);
udev_monitor = NULL;
udev_unref(udev);
}
#ifdef CONFIG_UDEV_KMS
/* Find the last occurrence of the needle in haystack */
static char *strrstr(const char *haystack, const char *needle)
{
char *prev, *last, *tmp;
prev = strstr(haystack, needle);
if (!prev)
return NULL;
last = prev;
tmp = prev + 1;
while (tmp) {
last = strstr(tmp, needle);
if (!last)
return prev;
else {
prev = last;
tmp = prev + 1;
}
}
return last;
}
static void
config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback)
{
struct OdevAttributes *attribs = config_odev_allocate_attributes();
const char *value, *str;
attribs->path = XNFstrdup(path);
attribs->syspath = XNFstrdup(syspath);
attribs->major = major;
attribs->minor = minor;
value = udev_device_get_property_value(udev_device, "ID_PATH");
if (value && (str = strrstr(value, "pci-"))) {
value = str;
if ((str = strstr(value, "usb-")))
value = str;
attribs->busid = XNFstrdup(value);
attribs->busid[3] = ':';
}
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
}
void
config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *device;
udev = udev_monitor_get_udev(udev_monitor);
enumerate = udev_enumerate_new(udev);
if (!enumerate)
return;
udev_enumerate_add_match_subsystem(enumerate, "drm");
udev_enumerate_add_match_sysname(enumerate, "card[0-9]*");
#ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
if (ServerIsNotSeat0())
udev_enumerate_add_match_tag(enumerate, SeatId);
#endif
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(device, devices) {
const char *syspath = udev_list_entry_get_name(device);
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);
const char *subsys = udev_device_get_subsystem(udev_device);
if (!path || !syspath || !subsys)
goto no_probe;
else if (strcmp(subsys, "drm") != 0)
goto no_probe;
else if (strncmp(sysname, "card", 4) != 0)
goto no_probe;
else if (!check_seat(udev_device))
goto no_probe;
config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum),
minor(devnum), probe_callback);
no_probe:
udev_device_unref(udev_device);
}
udev_enumerate_unref(enumerate);
return;
}
#endif

View File

@ -1,262 +0,0 @@
/*
* Copyright (c) 2011 Matthieu Herrb
*
* 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.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsksymdef.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "input.h"
#include "inputstr.h"
#include "os.h"
#include "config-backends.h"
#define WSCONS_KBD_DEVICE "/dev/wskbd"
#define WSCONS_MOUSE_PREFIX "/dev/wsmouse"
#define KB_OVRENC \
{ KB_UK, "gb" }, \
{ KB_SV, "se" }, \
{ KB_SG, "ch" }, \
{ KB_SF, "ch" }, \
{ KB_LA, "latam" }, \
{ KB_CF, "ca" }
struct nameint {
int val;
char *name;
} kbdenc[] = {
KB_OVRENC,
KB_ENCTAB,
{0}
};
struct nameint kbdvar[] = {
{KB_NODEAD | KB_SG, "de_nodeadkeys"},
{KB_NODEAD | KB_SF, "fr_nodeadkeys"},
{KB_SF, "fr"},
{KB_DVORAK | KB_CF, "fr-dvorak"},
{KB_DVORAK | KB_FR, "bepo"},
{KB_DVORAK, "dvorak"},
{KB_CF, "fr-legacy"},
{KB_NODEAD, "nodeadkeys"},
{0}
};
struct nameint kbdopt[] = {
{KB_SWAPCTRLCAPS, "ctrl:swapcaps"},
{0}
};
struct nameint kbdmodel[] = {
{WSKBD_TYPE_ZAURUS, "zaurus"},
{0}
};
static void
wscons_add_keyboard(void)
{
InputAttributes attrs = { };
DeviceIntPtr dev = NULL;
InputOption *input_options = NULL;
char *config_info = NULL;
int fd, i, rc;
unsigned int type;
kbd_t wsenc = 0;
/* Find keyboard configuration */
fd = open(WSCONS_KBD_DEVICE, O_RDWR | O_NONBLOCK | O_EXCL);
if (fd == -1) {
LogMessage(X_ERROR, "wskbd: open %s: %s\n",
WSCONS_KBD_DEVICE, strerror(errno));
return;
}
if (ioctl(fd, WSKBDIO_GETENCODING, &wsenc) == -1) {
LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GETENCODING) "
"failed: %s\n", strerror(errno));
close(fd);
return;
}
if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) {
LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GTYPE) "
"failed: %s\n", strerror(errno));
close(fd);
return;
}
close(fd);
input_options = input_option_new(input_options, "_source", "server/wscons");
if (input_options == NULL)
return;
LogMessage(X_INFO, "config/wscons: checking input device %s\n",
WSCONS_KBD_DEVICE);
input_options = input_option_new(input_options, "name", WSCONS_KBD_DEVICE);
input_options = input_option_new(input_options, "driver", "kbd");
config_info = Xprintf("wscons:%s", WSCONS_KBD_DEVICE);
if (!config_info)
goto unwind;
if (KB_ENCODING(wsenc) == KB_USER) {
/* Ignore wscons "user" layout */
LogMessageVerb(X_INFO, 3, "wskbd: ignoring \"user\" layout\n");
goto kbd_config_done;
}
for (i = 0; kbdenc[i].val; i++)
if (KB_ENCODING(wsenc) == kbdenc[i].val) {
LogMessageVerb(X_INFO, 3, "wskbd: using layout %s\n",
kbdenc[i].name);
input_options = input_option_new(input_options,
"xkb_layout", kbdenc[i].name);
break;
}
for (i = 0; kbdvar[i].val; i++)
if (wsenc == kbdvar[i].val || KB_VARIANT(wsenc) == kbdvar[i].val) {
LogMessageVerb(X_INFO, 3, "wskbd: using variant %s\n",
kbdvar[i].name);
input_options = input_option_new(input_options,
"xkb_variant", kbdvar[i].name);
break;
}
for (i = 0; kbdopt[i].val; i++)
if (KB_VARIANT(wsenc) == kbdopt[i].val) {
LogMessageVerb(X_INFO, 3, "wskbd: using option %s\n",
kbdopt[i].name);
input_options = input_option_new(input_options,
"xkb_options", kbdopt[i].name);
break;
}
for (i = 0; kbdmodel[i].val; i++)
if (type == kbdmodel[i].val) {
LogMessageVerb(X_INFO, 3, "wskbd: using model %s\n",
kbdmodel[i].name);
input_options = input_option_new(input_options,
"xkb_model", kbdmodel[i].name);
break;
}
kbd_config_done:
attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
rc = NewInputDeviceRequest(input_options, &attrs, &dev);
if (rc != Success)
goto unwind;
for (; dev; dev = dev->next) {
free(dev->config_info);
dev->config_info = strdup(config_info);
}
unwind:
input_option_free_list(&input_options);
}
static void
wscons_add_pointer(const char *path, const char *driver, int flags)
{
InputAttributes attrs = { };
DeviceIntPtr dev = NULL;
InputOption *input_options = NULL;
char *config_info = NULL;
int rc;
config_info = Xprintf("wscons:%s", path);
if (!config_info)
return;
input_options = input_option_new(input_options, "_source", "server/wscons");
if (input_options == NULL)
return;
input_options = input_option_new(input_options, "name", strdup(path));
input_options = input_option_new(input_options, "driver", strdup(driver));
input_options = input_option_new(input_options, "device", strdup(path));
LogMessage(X_INFO, "config/wscons: checking input device %s\n", path);
attrs.flags |= flags;
rc = NewInputDeviceRequest(input_options, &attrs, &dev);
if (rc != Success)
goto unwind;
for (; dev; dev = dev->next) {
free(dev->config_info);
dev->config_info = strdup(config_info);
}
unwind:
input_option_free_list(&input_options);
}
static void
wscons_add_pointers(void)
{
char devname[256];
int fd, i, wsmouse_type;
/* Check pointing devices */
for (i = 0; i < 4; i++) {
snprintf(devname, sizeof(devname), "%s%d", WSCONS_MOUSE_PREFIX, i);
LogMessageVerb(X_INFO, 10, "wsmouse: checking %s\n", devname);
fd = open_device(devnamem O_RDWR | O_NONBLOCK | O_EXCL);
if (fd == -1) {
LogMessageVerb(X_WARNING, 10, "%s: %s\n", devname, strerror(errno));
continue;
}
if (ioctl(fd, WSMOUSEIO_GTYPE, &wsmouse_type) != 0) {
LogMessageVerb(X_WARNING, 10,
"%s: WSMOUSEIO_GTYPE failed\n", devname);
close(fd);
continue;
}
close(fd);
switch (wsmouse_type) {
case WSMOUSE_TYPE_SYNAPTICS:
wscons_add_pointer(devname, "synaptics", ATTR_TOUCHPAD);
break;
case WSMOUSE_TYPE_TPANEL:
wscons_add_pointer(devname, "ws", ATTR_TOUCHSCREEN);
break;
default:
break;
}
}
/* Add a default entry catching all other mux elements as "mouse" */
wscons_add_pointer(WSCONS_MOUSE_PREFIX, "mouse", ATTR_POINTER);
}
int
config_wscons_init(void)
{
wscons_add_keyboard();
wscons_add_pointers();
return 1;
}
void
config_wscons_fini(void)
{
/* Not much to do ? */
}

View File

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
<!-- The way this works:
Match against some input device (see the HAL specification for more
information), and then merge in keys, which you can use to specify
the configuration similar to the way you would in xorg.conf. You will
need to restart HAL after making changes. If you are having issues,
starting X with the -logverbose 7 flag may yield useful information.
Keys Supported:
Key "input.x11_driver" (string)
This specifies the driver to use. You MUST specify this option,
or a driver will not be loaded and the rest will be ignored by
Xorg
Key "input.x11_options.<option name>" (string)
This allows you to specify arbitrary options to pass to the driver.
Anything you would normally specify in xorg.conf goes here. So, for
option "Mode" in xorg.conf, you would specify the key name of
"input.x11_options.Mode".
Do not specify "input.x11_options.Device" since "input.device"
will be used automatically.
You MUST specify all options as strings, otherwise the server will
ignore them.
Legacy Keys
"input.xkb.rules"
"input.xkb.model"
"input.xkb.layout"
"input.xkb.variant"
"input.xkb.options"
These keys are deprecated. Use these instead:
"input.x11_options.XkbRules"
"input.x11_options.XkbModel"
"input.x11_options.XkbLayout"
"input.x11_options.XkbVariant"
"input.x11_options.XkbOptions"
See the evdev documentation for more information.
FIXME: Support tablets too.
TODO: I think its fixed, can't test
-->
<match key="info.capabilities" contains="input.mouse">
<merge key="input.x11_driver" type="string">mouse</merge>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
string="Linux">
<merge key="input.x11_driver" type="string">evdev</merge>
</match>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
string="SunOS">
<match key="input.device" contains="usb">
<merge key="input.x11_options.StreamsModule" type="string">usbms</merge>
<merge key="input.x11_options.Protocol" type="string">VUID</merge>
</match>
</match>
</match>
<match key="info.capabilities" contains="input.keys">
<merge key="input.x11_options.XkbRules" type="string">base</merge>
<!-- If we're using Linux, we use evdev by default (falling back to
kbd otherwise). -->
<merge key="input.x11_driver" type="string">kbd</merge>
<merge key="input.x11_options.XkbModel" type="string">pc105</merge>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
string="Linux">
<merge key="input.x11_driver" type="string">evdev</merge>
<merge key="input.x11_options.XkbModel" type="string">evdev</merge>
</match>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
string="SunOS">
<match key="input.device" contains="usb">
<merge key="input.x11_options.StreamsModule" type="string">usbkbm</merge>
<merge key="input.x11_options.Protocol" type="string">VUID</merge>
</match>
</match>
<merge key="input.x11_options.XkbLayout" type="string">us</merge>
<merge key="input.x11_options.XkbVariant" type="string" />
</match>
</device>
</deviceinfo>

View File

@ -99,7 +99,6 @@ Equipment Corporation.
#include <X11/fonts/libxfont2.h>
#include "opaque.h"
#include "servermd.h"
#include "hotplug.h"
#include "dixfont.h"
#include "extnsionst.h"
#include "privates.h"

View File

@ -1,83 +0,0 @@
/*
* Copyright © 2006-2007 Daniel Stone
*
* 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: Daniel Stone <daniel@fooishbar.org>
*/
#ifndef HOTPLUG_H
#define HOTPLUG_H
#include "list.h"
extern _X_EXPORT void config_pre_init(void);
extern _X_EXPORT void config_init(void);
extern _X_EXPORT void config_fini(void);
/* Bump this each time you add something to the struct
* so that drivers can easily tell what is available
*/
#define ODEV_ATTRIBUTES_VERSION 1
struct OdevAttributes {
/* path to kernel device node - Linux e.g. /dev/dri/card0 */
char *path;
/* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */
char *syspath;
/* DRI-style bus id */
char *busid;
/* Server managed FD */
int fd;
/* Major number of the device node pointed to by ODEV_ATTRIB_PATH */
int major;
/* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */
int minor;
/* kernel driver name */
char *driver;
};
/* Note starting with xserver 1.16 this function never fails */
struct OdevAttributes *
config_odev_allocate_attributes(void);
void
config_odev_free_attributes(struct OdevAttributes *attribs);
typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs);
void config_odev_probe(config_odev_probe_proc_ptr probe_callback);
#ifdef CONFIG_UDEV_KMS
void NewGPUDeviceRequest(struct OdevAttributes *attribs);
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 */

View File

@ -83,16 +83,6 @@ elif cc.compiles('''
endif
conf_data.set('HAVE_LIBBSD', libbsd_dep.found())
# Note: this symbol is used by libXtrans.
conf_data.set('HAVE_SYSTEMD_DAEMON', libsystemd_daemon_dep.found())
conf_data.set('CONFIG_UDEV', build_udev)
conf_data.set('CONFIG_UDEV_KMS', build_udev_kms)
conf_data.set('HAVE_DBUS', build_dbus)
conf_data.set('CONFIG_HAL', build_hal)
conf_data.set('SYSTEMD_LOGIND', build_systemd_logind)
conf_data.set('NEED_DBUS', build_systemd_logind or build_hal)
conf_data.set('CONFIG_WSCONS', host_machine.system() == 'openbsd')
conf_data.set('HAVE_XSHMFENCE', xshmfence_dep.found())
conf_data.set('WITH_LIBDRM', libdrm_required)
conf_data.set('GLAMOR_HAS_EGL_QUERY_DMABUF',
@ -273,11 +263,6 @@ endif
conf_data.set_quoted('XKB_DFLT_RULES', get_option('xkb_default_rules'))
conf_data.set_quoted('__XSERVERNAME__', 'Xorg')
conf_data.set('CSRG_BASED', csrg_based)
conf_data.set('PCCONS_SUPPORT', supports_pccons)
conf_data.set('PCVT_SUPPORT', supports_pcvt)
conf_data.set('SYSCONS_SUPPORT', supports_syscons)
conf_data.set('WSCONS_SUPPORT', supports_wscons)
conf_data.set('XSERVER_PLATFORM_BUS', build_udev_kms)
configure_file(output : 'dix-config.h',
configuration : conf_data)

View File

@ -95,15 +95,6 @@ xkbcomp_dep = dependency('xkbcomp', required: false)
xkbfile_dep = dependency('xkbfile')
xfont2_dep = dependency('xfont2', version: '>= 2.0')
dbus_required = get_option('systemd_logind') == 'true'
dbus_dep = dependency('dbus-1', version: '>= 1.0', required: dbus_required)
# libsystemd-daemon was moved into libsystemd in version 209
libsystemd_daemon_dep = dependency('libsystemd', version: '>= 209', required: false)
if not libsystemd_daemon_dep.found()
libsystemd_daemon_dep = dependency('libsystemd-daemon', required: false)
endif
build_hashtable = false
# Resolve default values of some options
@ -155,23 +146,8 @@ else
default_font_path = dfp
endif
hal_option = get_option('hal')
glamor_option = get_option('glamor')
build_udev = get_option('udev')
build_udev_kms = get_option('udev_kms')
if ['windows', 'darwin', 'cygwin'].contains(host_machine.system())
build_udev = false
build_udev_kms = false
hal_option = 'false'
endif
if get_option('systemd_logind') == 'auto'
build_systemd_logind = build_udev_kms and dbus_dep.found()
else
build_systemd_logind = get_option('systemd_logind') == 'true'
endif
with_dtrace = get_option('dtrace')
if with_dtrace
dtrace = find_program('dtrace', required: true)
@ -215,32 +191,6 @@ else
build_ipv6 = get_option('ipv6') == 'true'
endif
hal_dep = []
if hal_option == 'auto'
if not build_udev
hal_dep = dependency('hal', required: false)
build_hal = hal_dep.found()
else
build_hal = false
endif
else
build_hal = hal_option == 'true'
if build_hal
hal_dep = dependency('hal')
endif
endif
if build_udev and build_hal
error('Hotplugging through both libudev and hal not allowed')
endif
build_dbus = build_hal or build_systemd_logind
udev_dep = dependency('', required:false)
if build_udev or build_udev_kms
udev_dep = dependency('libudev', version: '>= 143')
endif
if glamor_option == 'auto'
build_glamor = build_xwayland
else
@ -437,7 +387,6 @@ common_dep = [
xcmiscproto_dep,
bigreqsproto_dep,
xtrans_dep,
libsystemd_daemon_dep,
videoproto_dep,
compositeproto_dep,
@ -540,7 +489,6 @@ manpage_config.set('default_font_path', default_font_path)
subdir('include')
# X server core
subdir('config')
subdir('dix')
subdir('dri3')
subdir('glx')

View File

@ -43,12 +43,6 @@ option('listen_unix', type: 'boolean', value: true,
option('listen_local', type: 'boolean', value: true,
description: 'Listen on local by default')
option('udev', type: 'boolean', value: 'true')
option('udev_kms', type: 'boolean', value: 'true')
option('hal', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable HAL integration')
option('systemd_logind', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable systemd-logind integration')
option('dpms', type: 'boolean', value: true,
description: 'Xorg DPMS extension')
option('xf86bigfont', type: 'boolean', value: false,