Merge branch 'server-1.5-branch' of git+ssh://herrb@git.freedesktop.org/git/xorg/xserver into server-1.5-branch

This commit is contained in:
Matthieu Herrb 2008-06-12 14:22:32 -06:00 committed by Matthieu Herrb
commit a645b47f04
7 changed files with 279 additions and 112 deletions

View file

@ -420,10 +420,13 @@ findFirstSet(unsigned int v)
static void
initGlxVisual(VisualPtr visual, __GLXconfig *config)
{
int maxBits;
maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
config->visualID = visual->vid;
visual->class = glxConvertToXVisualType(config->visualType);
visual->bitsPerRGBValue = config->redBits;
visual->ColormapEntries = 1 << config->redBits;
visual->bitsPerRGBValue = maxBits;
visual->ColormapEntries = 1 << maxBits;
visual->nplanes = config->redBits + config->greenBits + config->blueBits;
visual->redMask = config->redMask;

View file

@ -38,19 +38,30 @@
#include "config-backends.h"
#include "os.h"
#define TYPE_NONE 0
#define TYPE_KEYS 1
#define TYPE_POINTER 2
#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;
};
static void
remove_device(DeviceIntPtr dev)
{
DebugF("[config/hal] removing device %s\n", dev->name);
/* this only gets called for devices that have already been added */
LogMessage(X_INFO, "config/hal: removing device %s\n", dev->name);
/* Call PIE here so we don't try to dereference a device that's
* already been removed. */
@ -107,7 +118,7 @@ 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);
DebugF("[config/hal] getting %s on %s returned %s\n", name, udi, prop);
LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop);
if (prop) {
ret = xstrdup(prop);
libhal_free_string(prop);
@ -119,6 +130,9 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
return ret;
}
/* this function is no longer used... keep it here in case its needed in
* the future. */
#if 0
static char *
get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
{
@ -152,117 +166,202 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
return ret;
}
#endif
static void
device_added(LibHalContext *hal_ctx, const char *udi)
{
char **props;
char *path = NULL, *driver = NULL, *name = NULL, *xkb_rules = NULL;
char *xkb_model = NULL, *xkb_layout = NULL, *xkb_variant = NULL;
char *xkb_options = NULL, *config_info = NULL;
char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
InputOption *options = NULL, *tmpo = NULL;
DeviceIntPtr dev;
DBusError error;
int type = TYPE_NONE;
int i;
struct xkb_options xkb_opts = {0};
LibHalPropertySet *set = NULL;
LibHalPropertySetIterator set_iter;
char *psi_key = NULL, *tmp_val;
dbus_error_init(&error);
props = libhal_device_get_property_strlist(hal_ctx, udi,
"info.capabilities", &error);
if (!props) {
DebugF("[config/hal] couldn't get capabilities for %s: %s (%s)\n",
udi, error.name, error.message);
goto out_error;
}
for (i = 0; props[i]; i++) {
/* input.keys is the new, of which input.keyboard is a subset, but
* input.keyboard is the old 'we have keys', so we have to keep it
* around. */
if (strcmp(props[i], "input.keys") == 0 ||
strcmp(props[i], "input.keyboard") == 0)
type |= TYPE_KEYS;
if (strcmp(props[i], "input.mouse") == 0 ||
strcmp(props[i], "input.touchpad") == 0)
type |= TYPE_POINTER;
}
libhal_free_string_array(props);
if (type == TYPE_NONE)
goto out_error;
driver = get_prop_string(hal_ctx, udi, "input.x11_driver");
path = get_prop_string(hal_ctx, udi, "input.device");
if (!driver || !path) {
DebugF("[config/hal] no driver or path specified for %s\n", udi);
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;
}
name = get_prop_string(hal_ctx, udi, "info.product");
if (!name)
name = xstrdup("(unnamed)");
if (type & TYPE_KEYS) {
xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb.rules");
xkb_model = get_prop_string(hal_ctx, udi, "input.xkb.model");
xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb.layout");
xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb.variant");
xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb.options");
options = xcalloc(sizeof(*options), 1);
if (!options){
LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n");
goto unwind;
}
options = xcalloc(sizeof(*options), 1);
options->key = xstrdup("_source");
options->value = xstrdup("server/hal");
if (!options->key || !options->value) {
ErrorF("[config] couldn't allocate first key/value pair\n");
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. */
add_option(&options, "path", path);
add_option(&options, "device", path);
add_option(&options, "driver", driver);
add_option(&options, "name", name);
config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */
if (!config_info)
if (!config_info) {
LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
goto unwind;
}
sprintf(config_info, "hal:%s", udi);
if (xkb_rules)
add_option(&options, "xkb_rules", xkb_rules);
if (xkb_model)
add_option(&options, "xkb_model", xkb_model);
if (xkb_layout)
add_option(&options, "xkb_layout", xkb_layout);
if (xkb_variant)
add_option(&options, "xkb_variant", xkb_variant);
if (xkb_options)
add_option(&options, "xkb_options", xkb_options);
/* 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);
DebugF("[config/hal] Adding device %s\n", name);
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)){
/* only support strings for all values */
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
if (tmp_val){
char* tmp;
/* 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")))
{
if (!strcasecmp(&tmp[3], "layout"))
{
if (xkb_opts.layout)
xfree(xkb_opts.layout);
xkb_opts.layout = strdup(tmp_val);
} else if (!strcasecmp(&tmp[3], "model"))
{
if (xkb_opts.model)
xfree(xkb_opts.model);
xkb_opts.model = strdup(tmp_val);
} else if (!strcasecmp(&tmp[3], "rules"))
{
if (xkb_opts.rules)
xfree(xkb_opts.rules);
xkb_opts.rules = strdup(tmp_val);
} else if (!strcasecmp(&tmp[3], "variant"))
{
if (xkb_opts.variant)
xfree(xkb_opts.variant);
xkb_opts.variant = strdup(tmp_val);
}
} else
{
/* all others */
add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val);
xfree(tmp_val);
}
}
} else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){
/* only support strings for all values */
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
if (tmp_val){
char* tmp;
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);
}
xfree(tmp_val);
}
}
}
/* psi_key doesn't need to be freed */
libhal_psi_next(&set_iter);
}
/* Now add xkb options */
if (xkb_opts.layout)
add_option(&options, "xkb_layout", xkb_opts.layout);
if (xkb_opts.rules)
add_option(&options, "xkb_rules", xkb_opts.rules);
if (xkb_opts.variant)
add_option(&options, "xkb_variant", xkb_opts.variant);
if (xkb_opts.model)
add_option(&options, "xkb_model", xkb_opts.model);
/* 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 (NewInputDeviceRequest(options, &dev) != Success) {
ErrorF("[config/hal] NewInputDeviceRequest failed\n");
LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n");
dev = NULL;
goto unwind;
}
for (; dev; dev = dev->next)
for (; dev; dev = dev->next){
if (dev->config_info)
xfree(dev->config_info);
dev->config_info = xstrdup(config_info);
}
unwind:
if (set)
libhal_free_property_set(set);
if (path)
xfree(path);
if (driver)
xfree(driver);
if (name)
xfree(name);
if (xkb_rules)
xfree(xkb_rules);
if (xkb_model)
xfree(xkb_model);
if (xkb_layout)
xfree(xkb_layout);
if (xkb_variant)
xfree(xkb_variant);
if (xkb_options)
xfree(xkb_options);
if (config_info)
xfree(config_info);
while (!dev && (tmpo = options)) {
@ -272,7 +371,15 @@ unwind:
xfree(tmpo);
}
out_error:
if (xkb_opts.layout)
xfree(xkb_opts.layout);
if (xkb_opts.rules)
xfree(xkb_opts.rules);
if (xkb_opts.model)
xfree(xkb_opts.model);
if (xkb_opts.variant)
xfree(xkb_opts.variant);
dbus_error_free(&error);
return;
@ -288,7 +395,7 @@ disconnect_hook(void *data)
if (dbus_connection_get_is_connected(info->system_bus)) {
dbus_error_init(&error);
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
DebugF("[config/hal] couldn't shut down context: %s (%s)\n",
LogMessage(X_WARNING, "config/hal: disconnect_hook couldn't shut down context: %s (%s)\n",
error.name, error.message);
dbus_error_free(&error);
}
@ -314,21 +421,21 @@ connect_hook(DBusConnection *connection, void *data)
if (!info->hal_ctx)
info->hal_ctx = libhal_ctx_new();
if (!info->hal_ctx) {
ErrorF("[config/hal] couldn't create HAL context\n");
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)) {
ErrorF("[config/hal] couldn't associate HAL context with bus\n");
LogMessage(X_ERROR, "config/hal: couldn't associate HAL context with bus\n");
goto out_ctx;
}
if (!libhal_ctx_init(info->hal_ctx, &error)) {
ErrorF("[config/hal] couldn't initialise context: %s (%s)\n",
LogMessage(X_ERROR, "config/hal: couldn't initialise context: %s (%s)\n",
error.name, error.message);
goto out_ctx;
}
if (!libhal_device_property_watch_all(info->hal_ctx, &error)) {
ErrorF("[config/hal] couldn't watch all properties: %s (%s)\n",
LogMessage(X_ERROR, "config/hal: couldn't watch all properties: %s (%s)\n",
error.name, error.message);
goto out_ctx2;
}
@ -348,7 +455,7 @@ connect_hook(DBusConnection *connection, void *data)
out_ctx2:
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
DebugF("[config/hal] couldn't shut down context: %s (%s)\n",
LogMessage(X_WARNING, "config/hal: couldn't shut down context: %s (%s)\n",
error.name, error.message);
out_ctx:
libhal_ctx_free(info->hal_ctx);
@ -376,10 +483,13 @@ config_hal_init(void)
hal_info.hal_ctx = NULL;
if (!config_dbus_core_add_hook(&hook)) {
ErrorF("[config/hal] failed to add D-Bus hook\n");
LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n");
return 0;
}
/* verbose message */
LogMessageVerb(X_INFO,7,"config/hal: initialized");
return 1;
}

View file

@ -1,7 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
<!-- FIXME: Support tablets too. -->
<!-- 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.
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.
You will probably want to add the following option to the ServerFlags of
your xorg.conf:
Option "AllowEmptyInput" "True"
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"
@ -11,21 +61,21 @@
</match>
<match key="info.capabilities" contains="input.keys">
<merge key="input.xkb.rules" type="string">base</merge>
<merge key="input.x11_options.XkbRules" type="string">base</merge>
<!-- If we're using Linux, we use evdev by default (falling back to
keyboard otherwise). -->
<merge key="input.x11_driver" type="string">keyboard</merge>
<merge key="input.xkb.model" type="string">pc105</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.xkb.model" type="string">evdev</merge>
<merge key="input.x11_options.XkbModel" type="string">evdev</merge>
</match>
<merge key="input.xkb.layout" type="string">us</merge>
<merge key="input.x11_options.XkbLayout" type="string">us</merge>
<merge key="input.xkb.variant" type="string" />
<merge key="input.x11_options.XkbVariant" type="string" />
</match>
</device>
</deviceinfo>

View file

@ -1025,6 +1025,8 @@ XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la'
AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1,
[Do not have 'strcasecmp'.]))
AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1,
[Do not have 'strncasecmp'.]))
if test "x$NULL_ROOT_CURSOR" = xyes; then
AC_DEFINE(NULL_ROOT_CURSOR, 1, [Use an empty root cursor])

View file

@ -229,6 +229,7 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
xDbeSwapAction swapAction;
VisualID visual;
int status;
int add_index;
REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
@ -299,14 +300,6 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
return(BadAlloc);
bzero(pDbeWindowPriv, sizeof(DbeWindowPrivRec));
/* Make the window priv a DBE window priv resource. */
if (!AddResource(stuff->buffer, dbeWindowPrivResType,
(pointer)pDbeWindowPriv))
{
xfree(pDbeWindowPriv);
return(BadAlloc);
}
/* Fill out window priv information. */
pDbeWindowPriv->pWindow = pWin;
pDbeWindowPriv->width = pWin->drawable.width;
@ -321,14 +314,15 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
/* Initialize the buffer ID list. */
pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
pDbeWindowPriv->IDs[0] = stuff->buffer;
for (i = 1; i < DBE_INIT_MAX_IDS; i++)
add_index = 0;
for (i = 0; i < DBE_INIT_MAX_IDS; i++)
{
pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
}
/* Actually connect the window priv to the window. */
dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
} /* if -- There is no buffer associated with the window. */
@ -354,7 +348,6 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
/* No more room in the ID array -- reallocate another array. */
XID *pIDs;
/* Setup an array pointer for the realloc operation below. */
if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
{
@ -391,16 +384,7 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
}
/* Finally, record the buffer ID in the array. */
pDbeWindowPriv->IDs[i] = stuff->buffer;
/* Associate the new ID with an existing window priv. */
if (!AddResource(stuff->buffer, dbeWindowPrivResType,
(pointer)pDbeWindowPriv))
{
pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
return(BadAlloc);
}
add_index = i;
} /* else -- A buffer is already associated with the window. */
@ -409,13 +393,26 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
stuff->swapAction);
if ((status != Success) && (pDbeWindowPriv->nBufferIDs == 0))
if (status == Success)
{
pDbeWindowPriv->IDs[add_index] = stuff->buffer;
if (!AddResource(stuff->buffer, dbeWindowPrivResType,
(pointer)pDbeWindowPriv))
{
pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
if (pDbeWindowPriv->nBufferIDs == 0) {
status = BadAlloc;
goto out_free;
}
}
} else {
/* The DDX buffer allocation routine failed for the first buffer of
* this window.
*/
xfree(pDbeWindowPriv);
return(status);
if (pDbeWindowPriv->nBufferIDs == 0) {
goto out_free;
}
}
/* Increment the number of buffers (XIDs) associated with this window. */
@ -424,9 +421,13 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
/* Set swap action on all calls. */
pDbeWindowPriv->swapAction = stuff->swapAction;
return(status);
out_free:
dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
xfree(pDbeWindowPriv);
return (status);
} /* ProcDbeAllocateBackBufferName() */

View file

@ -1854,6 +1854,7 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
nextEnabledOutput(config, enabled, &o);
while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
test = mode;
for (p = o; nextEnabledOutput(config, enabled, &p); ) {
test = xf86OutputFindClosestMode(config->output[p], mode);
if (!test)

View file

@ -159,7 +159,7 @@ xf86OpenConsole()
xf86ConsOpen_t *driver;
#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
int result;
#ifdef __FreeBSD__
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
struct utsname uts;
#endif
vtmode_t vtmode;