diff options
Diffstat (limited to 'xorg-server')
49 files changed, 5817 insertions, 4961 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 3e3c67b63..38089a27c 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -716,7 +716,6 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) { int i; int key = 0, - bit = 0, last_valuator; KeyClassPtr k = NULL; @@ -750,7 +749,6 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) b = device->button; key = event->detail.key; - bit = 1 << (key & 7); /* Update device axis */ /* Check valuators first */ @@ -888,8 +886,6 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) Bool deactivateDeviceGrab = FALSE; int key = 0, rootX, rootY; ButtonClassPtr b; - KeyClassPtr k; - ValuatorClassPtr v; int ret = 0; int state, i; DeviceIntPtr mouse = NULL, kbd = NULL; @@ -953,9 +949,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) if (ret == DONT_PROCESS) return; - v = device->valuator; b = device->button; - k = device->key; if (IsMaster(device) || IsFloating(device)) CheckMotion(event, device); diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c index 6b4574854..6be27f3d1 100644 --- a/xorg-server/Xi/xipassivegrab.c +++ b/xorg-server/Xi/xipassivegrab.c @@ -256,9 +256,16 @@ ProcXIPassiveUngrabDevice(ClientPtr client) REQUEST(xXIPassiveUngrabDeviceReq); REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); - if (rc != Success) - return rc; + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; + else if (stuff->deviceid == XIAllMasterDevices) + dev = inputInfo.all_master_devices; + else + { + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (rc != Success) + return rc; + } if (stuff->grab_type != XIGrabtypeButton && stuff->grab_type != XIGrabtypeKeycode && diff --git a/xorg-server/config/config-backends.h b/xorg-server/config/config-backends.h index 0a2a22af0..35ab8a044 100644 --- a/xorg-server/config/config-backends.h +++ b/xorg-server/config/config-backends.h @@ -27,10 +27,10 @@ #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); -void add_option(InputOption **options, const char *key, const char *value); #ifdef CONFIG_UDEV int config_udev_init(void); diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c index 5a7b0ea17..9c28785c6 100644 --- a/xorg-server/config/config.c +++ b/xorg-server/config/config.c @@ -1,139 +1,124 @@ -/*
- * 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 "os.h"
-#include "inputstr.h"
-#include "hotplug.h"
-#include "config-backends.h"
-
-void
-config_init(void)
-{
-#ifdef CONFIG_UDEV
- if (!config_udev_init())
- ErrorF("[config] failed to initialise udev\n");
-#elif defined(CONFIG_NEED_DBUS)
- if (config_dbus_core_init()) {
-# ifdef CONFIG_DBUS_API
- if (!config_dbus_init())
- ErrorF("[config] failed to initialise D-Bus API\n");
-# endif
-# ifdef CONFIG_HAL
- if (!config_hal_init())
- ErrorF("[config] failed to initialise HAL\n");
-# endif
- }
- else {
- ErrorF("[config] failed to initialise D-Bus core\n");
- }
-#endif
-}
-
-void
-config_fini(void)
-{
-#if defined(CONFIG_UDEV)
- config_udev_fini();
-#elif defined(CONFIG_NEED_DBUS)
-# ifdef CONFIG_HAL
- config_hal_fini();
-# endif
-# ifdef CONFIG_DBUS_API
- config_dbus_fini();
-# endif
- config_dbus_core_fini();
-#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. */
- OsBlockSignals();
- ProcessInputEvents();
- DeleteInputDeviceRequest(dev);
- OsReleaseSignals();
-}
-
-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);
- }
-}
-
-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;
-}
-
-void
-add_option(InputOption **options, const char *key, const char *value)
-{
- if (!value || *value == '\0')
- return;
-
- for (; *options; options = &(*options)->next)
- ;
- *options = calloc(sizeof(**options), 1);
- if (!*options) /* Yeesh. */
- return;
- (*options)->key = strdup(key);
- (*options)->value = strdup(value);
- (*options)->next = NULL;
-}
+/* + * 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 "os.h" +#include "inputstr.h" +#include "hotplug.h" +#include "config-backends.h" + +void +config_init(void) +{ +#ifdef CONFIG_UDEV + if (!config_udev_init()) + ErrorF("[config] failed to initialise udev\n"); +#elif defined(CONFIG_NEED_DBUS) + if (config_dbus_core_init()) { +# ifdef CONFIG_DBUS_API + if (!config_dbus_init()) + ErrorF("[config] failed to initialise D-Bus API\n"); +# endif +# ifdef CONFIG_HAL + if (!config_hal_init()) + ErrorF("[config] failed to initialise HAL\n"); +# endif + } + else { + ErrorF("[config] failed to initialise D-Bus core\n"); + } +#endif +} + +void +config_fini(void) +{ +#if defined(CONFIG_UDEV) + config_udev_fini(); +#elif defined(CONFIG_NEED_DBUS) +# ifdef CONFIG_HAL + config_hal_fini(); +# endif +# ifdef CONFIG_DBUS_API + config_dbus_fini(); +# endif + config_dbus_core_fini(); +#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. */ + OsBlockSignals(); + ProcessInputEvents(); + DeleteInputDeviceRequest(dev); + OsReleaseSignals(); +} + +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); + } +} + +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; +} + diff --git a/xorg-server/config/dbus.c b/xorg-server/config/dbus.c index ec1008a4d..f0fc5686e 100644 --- a/xorg-server/config/dbus.c +++ b/xorg-server/config/dbus.c @@ -1,439 +1,407 @@ -/*
- * 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 <string.h>
-
-#include <X11/X.h>
-
-#include "config-backends.h"
-#include "opaque.h" /* for 'display': there should be a better way. */
-#include "input.h"
-#include "inputstr.h"
-
-#define API_VERSION 2
-
-#define MATCH_RULE "type='method_call',interface='org.x.config.input'"
-
-#define MALFORMED_MSG "[config/dbus] malformed message, dropping"
-#define MALFORMED_MESSAGE() { DebugF(MALFORMED_MSG "\n"); \
- ret = BadValue; \
- goto unwind; }
-#define MALFORMED_MESSAGE_ERROR() { DebugF(MALFORMED_MSG ": %s, %s", \
- error->name, error->message); \
- ret = BadValue; \
- goto unwind; }
-
-struct connection_info {
- char busobject[32];
- char busname[64];
- DBusConnection *connection;
-};
-
-static void
-reset_info(struct connection_info *info)
-{
- info->connection = NULL;
- info->busname[0] = '\0';
- info->busobject[0] = '\0';
-}
-
-static int
-add_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
-{
- DBusMessageIter iter, reply_iter, subiter;
- InputOption *tmpo = NULL, *options = NULL;
- char *tmp = NULL;
- int ret, err;
- DeviceIntPtr dev = NULL;
-
- dbus_message_iter_init_append(reply, &reply_iter);
-
- if (!dbus_message_iter_init(message, &iter)) {
- ErrorF("[config/dbus] couldn't initialise iterator\n");
- MALFORMED_MESSAGE();
- }
-
- options = calloc(sizeof(*options), 1);
- if (!options) {
- ErrorF("[config/dbus] couldn't allocate option\n");
- return BadAlloc;
- }
-
- options->key = strdup("_source");
- options->value = strdup("client/dbus");
- if (!options->key || !options->value) {
- ErrorF("[config/dbus] couldn't allocate first key/value pair\n");
- ret = BadAlloc;
- goto unwind;
- }
-
- /* signature should be [ss][ss]... */
- while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
- tmpo = calloc(sizeof(*tmpo), 1);
- if (!tmpo) {
- ErrorF("[config/dbus] couldn't allocate option\n");
- ret = BadAlloc;
- goto unwind;
- }
- tmpo->next = options;
- options = tmpo;
-
- dbus_message_iter_recurse(&iter, &subiter);
-
- if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
- MALFORMED_MESSAGE();
-
- dbus_message_iter_get_basic(&subiter, &tmp);
- if (!tmp)
- MALFORMED_MESSAGE();
- /* The _ prefix refers to internal settings, and may not be given by
- * the client. */
- if (tmp[0] == '_') {
- ErrorF("[config/dbus] attempted subterfuge: option name %s given\n",
- tmp);
- MALFORMED_MESSAGE();
- }
- options->key = strdup(tmp);
- if (!options->key) {
- ErrorF("[config/dbus] couldn't duplicate key!\n");
- ret = BadAlloc;
- goto unwind;
- }
-
- if (!dbus_message_iter_has_next(&subiter))
- MALFORMED_MESSAGE();
- dbus_message_iter_next(&subiter);
- if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
- MALFORMED_MESSAGE();
-
- dbus_message_iter_get_basic(&subiter, &tmp);
- if (!tmp)
- MALFORMED_MESSAGE();
- options->value = strdup(tmp);
- if (!options->value) {
- ErrorF("[config/dbus] couldn't duplicate option!\n");
- ret = BadAlloc;
- goto unwind;
- }
-
- dbus_message_iter_next(&iter);
- }
-
- ret = NewInputDeviceRequest(options, NULL, &dev);
- if (ret != Success) {
- DebugF("[config/dbus] NewInputDeviceRequest failed\n");
- goto unwind;
- }
-
- if (!dev) {
- DebugF("[config/dbus] NewInputDeviceRequest provided no device\n");
- ret = BadImplementation;
- goto unwind;
- }
-
- /* XXX: If we fail halfway through, we don't seem to have any way to
- * empty the iterator, so you'll end up with some device IDs,
- * plus an error. This seems to be a shortcoming in the D-Bus
- * API. */
- for (; dev; dev = dev->next) {
- if (!dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32,
- &dev->id)) {
- ErrorF("[config/dbus] couldn't append to iterator\n");
- ret = BadAlloc;
- goto unwind;
- }
- }
-
-unwind:
- if (ret != Success) {
- if (dev)
- RemoveDevice(dev, TRUE);
-
- err = -ret;
- dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
- }
-
- while (options) {
- tmpo = options;
- options = options->next;
- free(tmpo->key);
- free(tmpo->value);
- free(tmpo);
- }
-
- return ret;
-}
-
-static int
-remove_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
-{
- int deviceid, ret, err;
- DeviceIntPtr dev;
- DBusMessageIter iter, reply_iter;
-
- dbus_message_iter_init_append(reply, &reply_iter);
-
- if (!dbus_message_iter_init(message, &iter)) {
- ErrorF("[config/dbus] failed to init iterator\n");
- MALFORMED_MESSAGE();
- }
-
- if (!dbus_message_get_args(message, error, DBUS_TYPE_UINT32,
- &deviceid, DBUS_TYPE_INVALID)) {
- MALFORMED_MESSAGE_ERROR();
- }
-
- dixLookupDevice(&dev, deviceid, serverClient, DixDestroyAccess);
- if (!dev) {
- DebugF("[config/dbus] bogus device id %d given\n", deviceid);
- ret = BadMatch;
- goto unwind;
- }
-
- DebugF("[config/dbus] removing device %s (id %d)\n", dev->name, deviceid);
-
- /* Call PIE here so we don't try to dereference a device that's
- * already been removed. */
- OsBlockSignals();
- ProcessInputEvents();
- DeleteInputDeviceRequest(dev);
- OsReleaseSignals();
-
- ret = Success;
-
-unwind:
- err = (ret == Success) ? ret : -ret;
- dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
-
- return ret;
-}
-
-static int
-list_devices(DBusMessage *message, DBusMessage *reply, DBusError *error)
-{
- DeviceIntPtr dev;
- DBusMessageIter iter, subiter;
-
- dbus_message_iter_init_append(reply, &iter);
-
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL,
- &subiter)) {
- ErrorF("[config/dbus] couldn't init container\n");
- return BadAlloc;
- }
- if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UINT32,
- &dev->id)) {
- ErrorF("[config/dbus] couldn't append to iterator\n");
- return BadAlloc;
- }
- if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING,
- &dev->name)) {
- ErrorF("[config/dbus] couldn't append to iterator\n");
- return BadAlloc;
- }
- if (!dbus_message_iter_close_container(&iter, &subiter)) {
- ErrorF("[config/dbus] couldn't close container\n");
- return BadAlloc;
- }
- }
-
- return Success;
-}
-
-static int
-get_version(DBusMessage *message, DBusMessage *reply, DBusError *error)
-{
- DBusMessageIter iter;
- unsigned int version = API_VERSION;
-
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &version)) {
- ErrorF("[config/dbus] couldn't append version\n");
- return BadAlloc;
- }
-
- return Success;
-}
-
-static DBusHandlerResult
-message_handler(DBusConnection *connection, DBusMessage *message, void *data)
-{
- DBusError error;
- DBusMessage *reply;
- struct connection_info *info = data;
-
- /* ret is the overall D-Bus handler result, whereas err is the internal
- * X error from our individual functions. */
- int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- int err;
-
- DebugF("[config/dbus] received a message for %s\n",
- dbus_message_get_interface(message));
-
- dbus_error_init(&error);
-
- reply = dbus_message_new_method_return(message);
- if (!reply) {
- ErrorF("[config/dbus] failed to create reply\n");
- ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
- goto err_start;
- }
-
- if (strcmp(dbus_message_get_member(message), "add") == 0)
- err = add_device(message, reply, &error);
- else if (strcmp(dbus_message_get_member(message), "remove") == 0)
- err = remove_device(message, reply, &error);
- else if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
- err = list_devices(message, reply, &error);
- else if (strcmp(dbus_message_get_member(message), "version") == 0)
- err = get_version(message, reply, &error);
- else
- goto err_reply;
-
- /* Failure to allocate is a special case. */
- if (err == BadAlloc) {
- ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
- goto err_reply;
- }
-
- /* While failure here is always an OOM, we don't return that,
- * since that would result in devices being double-added/removed. */
- if (dbus_connection_send(info->connection, reply, NULL))
- dbus_connection_flush(info->connection);
- else
- ErrorF("[config/dbus] failed to send reply\n");
-
- ret = DBUS_HANDLER_RESULT_HANDLED;
-
-err_reply:
- dbus_message_unref(reply);
-err_start:
- dbus_error_free(&error);
-
- return ret;
-}
-
-static void
-connect_hook(DBusConnection *connection, void *data)
-{
- DBusError error;
- DBusObjectPathVTable vtable = { .message_function = message_handler, };
- struct connection_info *info = data;
-
- info->connection = connection;
-
- dbus_error_init(&error);
-
- dbus_bus_request_name(info->connection, info->busname, 0, &error);
- if (dbus_error_is_set(&error)) {
- ErrorF("[config/dbus] couldn't take over org.x.config: %s (%s)\n",
- error.name, error.message);
- goto err_start;
- }
-
- /* blocks until we get a reply. */
- dbus_bus_add_match(info->connection, MATCH_RULE, &error);
- if (dbus_error_is_set(&error)) {
- ErrorF("[config/dbus] couldn't add match: %s (%s)\n", error.name,
- error.message);
- goto err_name;
- }
-
- if (!dbus_connection_register_object_path(info->connection,
- info->busobject, &vtable,
- info)) {
- ErrorF("[config/dbus] couldn't register object path\n");
- goto err_match;
- }
-
- DebugF("[dbus] registered %s, %s\n", info->busname, info->busobject);
-
- dbus_error_free(&error);
-
- return;
-
-err_match:
- dbus_bus_remove_match(info->connection, MATCH_RULE, &error);
-err_name:
- dbus_bus_release_name(info->connection, info->busname, &error);
-err_start:
- dbus_error_free(&error);
-
- reset_info(info);
-}
-
-static void
-disconnect_hook(void *data)
-{
-}
-
-#if 0
-void
-pre_disconnect_hook(void)
-{
- DBusError error;
-
- dbus_error_init(&error);
- dbus_connection_unregister_object_path(connection_data->connection,
- connection_data->busobject);
- dbus_bus_remove_match(connection_data->connection, MATCH_RULE,
- &error);
- dbus_bus_release_name(connection_data->connection,
- connection_data->busname, &error);
- dbus_error_free(&error);
-}
-#endif
-
-static struct connection_info connection_data;
-static struct config_dbus_core_hook core_hook = {
- .connect = connect_hook,
- .disconnect = disconnect_hook,
- .data = &connection_data,
-};
-
-int
-config_dbus_init(void)
-{
- snprintf(connection_data.busname, sizeof(connection_data.busname),
- "org.x.config.display%d", atoi(display));
- snprintf(connection_data.busobject, sizeof(connection_data.busobject),
- "/org/x/config/%d", atoi(display));
-
- return config_dbus_core_add_hook(&core_hook);
-}
-
-void
-config_dbus_fini(void)
-{
- config_dbus_core_remove_hook(&core_hook);
- connection_data.busname[0] = '\0';
- connection_data.busobject[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 <string.h> + +#include <X11/X.h> + +#include "config-backends.h" +#include "opaque.h" /* for 'display': there should be a better way. */ +#include "input.h" +#include "inputstr.h" + +#define API_VERSION 2 + +#define MATCH_RULE "type='method_call',interface='org.x.config.input'" + +#define MALFORMED_MSG "[config/dbus] malformed message, dropping" +#define MALFORMED_MESSAGE() { DebugF(MALFORMED_MSG "\n"); \ + ret = BadValue; \ + goto unwind; } +#define MALFORMED_MESSAGE_ERROR() { DebugF(MALFORMED_MSG ": %s, %s", \ + error->name, error->message); \ + ret = BadValue; \ + goto unwind; } + +struct connection_info { + char busobject[32]; + char busname[64]; + DBusConnection *connection; +}; + +static void +reset_info(struct connection_info *info) +{ + info->connection = NULL; + info->busname[0] = '\0'; + info->busobject[0] = '\0'; +} + +static int +add_device(DBusMessage *message, DBusMessage *reply, DBusError *error) +{ + DBusMessageIter iter, reply_iter, subiter; + InputOption *input_options = NULL; + int ret, err; + DeviceIntPtr dev = NULL; + + dbus_message_iter_init_append(reply, &reply_iter); + + if (!dbus_message_iter_init(message, &iter)) { + ErrorF("[config/dbus] couldn't initialise iterator\n"); + MALFORMED_MESSAGE(); + } + + input_options = input_option_new(input_options, "_source", "client/dbus"); + if (!input_options) { + ErrorF("[config/dbus] couldn't allocate first key/value pair\n"); + ret = BadAlloc; + goto unwind; + } + + /* signature should be [ss][ss]... */ + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) { + char *key, *value; + dbus_message_iter_recurse(&iter, &subiter); + + if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING) + MALFORMED_MESSAGE(); + + dbus_message_iter_get_basic(&subiter, &key); + if (!key) + MALFORMED_MESSAGE(); + /* The _ prefix refers to internal settings, and may not be given by + * the client. */ + if (key[0] == '_') { + ErrorF("[config/dbus] attempted subterfuge: option name %s given\n", + key); + MALFORMED_MESSAGE(); + } + + if (!dbus_message_iter_has_next(&subiter)) + MALFORMED_MESSAGE(); + dbus_message_iter_next(&subiter); + if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING) + MALFORMED_MESSAGE(); + + dbus_message_iter_get_basic(&subiter, &value); + if (!value) + MALFORMED_MESSAGE(); + + input_options = input_option_new(input_options, key, value); + + dbus_message_iter_next(&iter); + } + + ret = NewInputDeviceRequest(input_options, NULL, &dev); + if (ret != Success) { + DebugF("[config/dbus] NewInputDeviceRequest failed\n"); + goto unwind; + } + + if (!dev) { + DebugF("[config/dbus] NewInputDeviceRequest provided no device\n"); + ret = BadImplementation; + goto unwind; + } + + /* XXX: If we fail halfway through, we don't seem to have any way to + * empty the iterator, so you'll end up with some device IDs, + * plus an error. This seems to be a shortcoming in the D-Bus + * API. */ + for (; dev; dev = dev->next) { + if (!dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, + &dev->id)) { + ErrorF("[config/dbus] couldn't append to iterator\n"); + ret = BadAlloc; + goto unwind; + } + } + +unwind: + if (ret != Success) { + if (dev) + RemoveDevice(dev, TRUE); + + err = -ret; + dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err); + } + + input_option_free_list(&input_options); + + return ret; +} + +static int +remove_device(DBusMessage *message, DBusMessage *reply, DBusError *error) +{ + int deviceid, ret, err; + DeviceIntPtr dev; + DBusMessageIter iter, reply_iter; + + dbus_message_iter_init_append(reply, &reply_iter); + + if (!dbus_message_iter_init(message, &iter)) { + ErrorF("[config/dbus] failed to init iterator\n"); + MALFORMED_MESSAGE(); + } + + if (!dbus_message_get_args(message, error, DBUS_TYPE_UINT32, + &deviceid, DBUS_TYPE_INVALID)) { + MALFORMED_MESSAGE_ERROR(); + } + + dixLookupDevice(&dev, deviceid, serverClient, DixDestroyAccess); + if (!dev) { + DebugF("[config/dbus] bogus device id %d given\n", deviceid); + ret = BadMatch; + goto unwind; + } + + DebugF("[config/dbus] removing device %s (id %d)\n", dev->name, deviceid); + + /* Call PIE here so we don't try to dereference a device that's + * already been removed. */ + OsBlockSignals(); + ProcessInputEvents(); + DeleteInputDeviceRequest(dev); + OsReleaseSignals(); + + ret = Success; + +unwind: + err = (ret == Success) ? ret : -ret; + dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err); + + return ret; +} + +static int +list_devices(DBusMessage *message, DBusMessage *reply, DBusError *error) +{ + DeviceIntPtr dev; + DBusMessageIter iter, subiter; + + dbus_message_iter_init_append(reply, &iter); + + for (dev = inputInfo.devices; dev; dev = dev->next) { + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, + &subiter)) { + ErrorF("[config/dbus] couldn't init container\n"); + return BadAlloc; + } + if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UINT32, + &dev->id)) { + ErrorF("[config/dbus] couldn't append to iterator\n"); + return BadAlloc; + } + if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, + &dev->name)) { + ErrorF("[config/dbus] couldn't append to iterator\n"); + return BadAlloc; + } + if (!dbus_message_iter_close_container(&iter, &subiter)) { + ErrorF("[config/dbus] couldn't close container\n"); + return BadAlloc; + } + } + + return Success; +} + +static int +get_version(DBusMessage *message, DBusMessage *reply, DBusError *error) +{ + DBusMessageIter iter; + unsigned int version = API_VERSION; + + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &version)) { + ErrorF("[config/dbus] couldn't append version\n"); + return BadAlloc; + } + + return Success; +} + +static DBusHandlerResult +message_handler(DBusConnection *connection, DBusMessage *message, void *data) +{ + DBusError error; + DBusMessage *reply; + struct connection_info *info = data; + + /* ret is the overall D-Bus handler result, whereas err is the internal + * X error from our individual functions. */ + int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + int err; + + DebugF("[config/dbus] received a message for %s\n", + dbus_message_get_interface(message)); + + dbus_error_init(&error); + + reply = dbus_message_new_method_return(message); + if (!reply) { + ErrorF("[config/dbus] failed to create reply\n"); + ret = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto err_start; + } + + if (strcmp(dbus_message_get_member(message), "add") == 0) + err = add_device(message, reply, &error); + else if (strcmp(dbus_message_get_member(message), "remove") == 0) + err = remove_device(message, reply, &error); + else if (strcmp(dbus_message_get_member(message), "listDevices") == 0) + err = list_devices(message, reply, &error); + else if (strcmp(dbus_message_get_member(message), "version") == 0) + err = get_version(message, reply, &error); + else + goto err_reply; + + /* Failure to allocate is a special case. */ + if (err == BadAlloc) { + ret = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto err_reply; + } + + /* While failure here is always an OOM, we don't return that, + * since that would result in devices being double-added/removed. */ + if (dbus_connection_send(info->connection, reply, NULL)) + dbus_connection_flush(info->connection); + else + ErrorF("[config/dbus] failed to send reply\n"); + + ret = DBUS_HANDLER_RESULT_HANDLED; + +err_reply: + dbus_message_unref(reply); +err_start: + dbus_error_free(&error); + + return ret; +} + +static void +connect_hook(DBusConnection *connection, void *data) +{ + DBusError error; + DBusObjectPathVTable vtable = { .message_function = message_handler, }; + struct connection_info *info = data; + + info->connection = connection; + + dbus_error_init(&error); + + dbus_bus_request_name(info->connection, info->busname, 0, &error); + if (dbus_error_is_set(&error)) { + ErrorF("[config/dbus] couldn't take over org.x.config: %s (%s)\n", + error.name, error.message); + goto err_start; + } + + /* blocks until we get a reply. */ + dbus_bus_add_match(info->connection, MATCH_RULE, &error); + if (dbus_error_is_set(&error)) { + ErrorF("[config/dbus] couldn't add match: %s (%s)\n", error.name, + error.message); + goto err_name; + } + + if (!dbus_connection_register_object_path(info->connection, + info->busobject, &vtable, + info)) { + ErrorF("[config/dbus] couldn't register object path\n"); + goto err_match; + } + + DebugF("[dbus] registered %s, %s\n", info->busname, info->busobject); + + dbus_error_free(&error); + + return; + +err_match: + dbus_bus_remove_match(info->connection, MATCH_RULE, &error); +err_name: + dbus_bus_release_name(info->connection, info->busname, &error); +err_start: + dbus_error_free(&error); + + reset_info(info); +} + +static void +disconnect_hook(void *data) +{ +} + +#if 0 +void +pre_disconnect_hook(void) +{ + DBusError error; + + dbus_error_init(&error); + dbus_connection_unregister_object_path(connection_data->connection, + connection_data->busobject); + dbus_bus_remove_match(connection_data->connection, MATCH_RULE, + &error); + dbus_bus_release_name(connection_data->connection, + connection_data->busname, &error); + dbus_error_free(&error); +} +#endif + +static struct connection_info connection_data; +static struct config_dbus_core_hook core_hook = { + .connect = connect_hook, + .disconnect = disconnect_hook, + .data = &connection_data, +}; + +int +config_dbus_init(void) +{ + snprintf(connection_data.busname, sizeof(connection_data.busname), + "org.x.config.display%d", atoi(display)); + snprintf(connection_data.busobject, sizeof(connection_data.busobject), + "/org/x/config/%d", atoi(display)); + + return config_dbus_core_add_hook(&core_hook); +} + +void +config_dbus_fini(void) +{ + config_dbus_core_remove_hook(&core_hook); + connection_data.busname[0] = '\0'; + connection_data.busobject[0] = '\0'; +} diff --git a/xorg-server/config/hal.c b/xorg-server/config/hal.c index 929643653..aa234ebb4 100644 --- a/xorg-server/config/hal.c +++ b/xorg-server/config/hal.c @@ -1,654 +1,642 @@ -/*
- * 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 "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 *options = NULL, *tmpo = 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_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.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;
-
- attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
-
- /* 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;
-
- free(parent);
- }
-
- options = calloc(sizeof(*options), 1);
- if (!options){
- LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n");
- goto unwind;
- }
-
- options->key = strdup("_source");
- options->value = strdup("server/hal");
- if (!options->key || !options->value) {
- 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);
-
- 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 */
- add_option(&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);
- }
- }
- }
- }
-
- /* 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);
- if (xkb_opts.options)
- add_option(&options, "xkb_options", xkb_opts.options);
- add_option(&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(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);
- while ((tmpo = options)) {
- options = tmpo->next;
- free(tmpo->key); /* NULL if dev != NULL */
- free(tmpo->value); /* NULL if dev != NULL */
- free(tmpo);
- }
-
- 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 config_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 (!config_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)
-{
- config_dbus_core_remove_hook(&hook);
-}
+/* + * 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 "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_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.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; + + attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id"); + + /* 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; + + free(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); + } + } + } + } + + /* 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 config_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 (!config_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) +{ + config_dbus_core_remove_hook(&hook); +} diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c index e7383dc36..1ba0d500d 100644 --- a/xorg-server/config/udev.c +++ b/xorg-server/config/udev.c @@ -35,6 +35,7 @@ #include "hotplug.h" #include "config-backends.h" #include "os.h" +#include "globals.h" #define UDEV_XKB_PROP_KEY "xkb" @@ -59,12 +60,13 @@ device_added(struct udev_device *udev_device) const char *syspath; const char *tags_prop; const char *key, *value, *tmp; - InputOption *options = NULL, *tmpo; + InputOption *input_options; InputAttributes attrs = {}; DeviceIntPtr dev = NULL; struct udev_list_entry *set, *entry; struct udev_device *parent; int rc; + const char *dev_seat; path = udev_device_get_devnode(udev_device); @@ -73,6 +75,16 @@ device_added(struct udev_device *udev_device) if (!path || !syspath) return; + dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); + if (!dev_seat) + dev_seat = "seat0"; + + if (SeatId && strcmp(dev_seat, SeatId)) + return; + + if (!SeatId && strcmp(dev_seat, "seat0")) + return; + if (!udev_device_get_property_value(udev_device, "ID_INPUT")) { LogMessageVerb(X_INFO, 10, "config/udev: ignoring device %s without " @@ -81,15 +93,10 @@ device_added(struct udev_device *udev_device) return; } - options = calloc(sizeof(*options), 1); - if (!options) + input_options = input_option_new(NULL, "_source", "server/udev"); + if (!input_options) return; - options->key = strdup("_source"); - options->value = strdup("server/udev"); - if (!options->key || !options->value) - goto unwind; - parent = udev_device_get_parent(udev_device); if (parent) { const char *ppath = udev_device_get_devnode(parent); @@ -114,17 +121,16 @@ device_added(struct udev_device *udev_device) == -1) attrs.usb_id = NULL; else - LOG_PROPERTY(path, "PRODUCT", product); + LOG_PROPERTY(ppath, "PRODUCT", product); } } if (!name) name = "(unnamed)"; else attrs.product = strdup(name); - add_option(&options, "name", name); - - add_option(&options, "path", path); - add_option(&options, "device", path); + 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); if (path) attrs.device = strdup(path); @@ -154,15 +160,15 @@ device_added(struct udev_device *udev_device) LOG_PROPERTY(path, key, value); tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1; if (!strcasecmp(tmp, "rules")) - add_option(&options, "xkb_rules", value); + input_options = input_option_new(input_options, "xkb_rules", value); else if (!strcasecmp(tmp, "layout")) - add_option(&options, "xkb_layout", value); + input_options = input_option_new(input_options, "xkb_layout", value); else if (!strcasecmp(tmp, "variant")) - add_option(&options, "xkb_variant", value); + input_options = input_option_new(input_options, "xkb_variant", value); else if (!strcasecmp(tmp, "model")) - add_option(&options, "xkb_model", value); + input_options = input_option_new(input_options, "xkb_model", value); else if (!strcasecmp(tmp, "options")) - add_option(&options, "xkb_options", value); + 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); @@ -187,22 +193,17 @@ device_added(struct udev_device *udev_device) } } - add_option(&options, "config_info", config_info); + input_options = input_option_new(input_options, "config_info", config_info); LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n", name, path); - rc = NewInputDeviceRequest(options, &attrs, &dev); + rc = NewInputDeviceRequest(input_options, &attrs, &dev); if (rc != Success) goto unwind; unwind: free(config_info); - while ((tmpo = options)) { - options = tmpo->next; - free(tmpo->key); /* NULL if dev != NULL */ - free(tmpo->value); /* NULL if dev != NULL */ - free(tmpo); - } + input_option_free_list(&input_options); free(attrs.usb_id); free(attrs.pnp_id); @@ -284,6 +285,9 @@ config_udev_init(void) udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL); udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL); /* For Wacom serial devices */ + if (SeatId && strcmp(SeatId, "seat0")) + udev_monitor_filter_add_match_tag(udev_monitor, SeatId); + if (udev_monitor_enable_receiving(udev_monitor)) { ErrorF("config/udev: failed to bind the udev monitor\n"); return 0; @@ -296,6 +300,9 @@ config_udev_init(void) udev_enumerate_add_match_subsystem(enumerate, "input"); udev_enumerate_add_match_subsystem(enumerate, "tty"); + if (SeatId && strcmp(SeatId, "seat0")) + udev_enumerate_add_match_tag(enumerate, SeatId); + udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(device, devices) { diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 0ccf25277..ab8a648a9 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -2406,7 +2406,6 @@ int AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { ScreenPtr screen; - DeviceIntPtr oldmaster; if (!dev || IsMaster(dev)) return BadDevice; @@ -2425,7 +2424,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) free(dev->spriteInfo->sprite); } - oldmaster = GetMaster(dev, MASTER_ATTACHED); dev->master = master; /* If device is set to floating, we need to create a sprite for it, @@ -2484,16 +2482,22 @@ GetPairedDevice(DeviceIntPtr dev) /** - * Returns the right master for the type of event needed. If the event is a - * keyboard event. - * This function may be called with a master device as argument. If so, the - * returned master is either the device itself or the paired master device. - * If dev is a floating slave device, NULL is returned. + * Returns the requested master for this device. + * The return values are: + * - MASTER_ATTACHED: the master for this device or NULL for a floating + * slave. + * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a + * floating slave + * - MASTER_POINTER: the master keyboard for this device or NULL for a + * floating slave + * - POINTER_OR_FLOAT: the master pointer for this device or the device for + * a floating slave + * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for + * a floating slave * - * @type ::MASTER_KEYBOARD or ::MASTER_POINTER or ::MASTER_ATTACHED - * @return The requested master device. In the case of MASTER_ATTACHED, this - * is the directly attached master to this device, regardless of the type. - * Otherwise, it is either the master keyboard or pointer for this device. + * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED, + * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT. + * @return The requested master device */ DeviceIntPtr GetMaster(DeviceIntPtr dev, int which) @@ -2502,12 +2506,15 @@ GetMaster(DeviceIntPtr dev, int which) if (IsMaster(dev)) master = dev; - else + else { master = dev->master; + if (!master && (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT)) + return dev; + } if (master && which != MASTER_ATTACHED) { - if (which == MASTER_KEYBOARD) + if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) { if (master->type != MASTER_KEYBOARD) master = GetPairedDevice(master); diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 8a4c6b9ac..fbe4fc953 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -408,6 +408,24 @@ static const Mask default_filter[128] = CantBeFiltered /* MappingNotify */ }; +static inline Mask +GetEventFilterMask(DeviceIntPtr dev, int evtype) +{ + return filters[dev ? dev->id : 0][evtype]; +} + +static inline Mask +GetXI2EventFilterMask(int evtype) +{ + return (1 << (evtype % 8)); +} + +static inline int +GetXI2EventFilterOffset(int evtype) +{ + return (evtype / 8); +} + /** * For the given event, return the matching event filter. This filter may then * be AND'ed with the selected event mask. @@ -429,14 +447,28 @@ GetEventFilter(DeviceIntPtr dev, xEvent *event) int evtype = 0; if (event->u.u.type != GenericEvent) - return filters[dev ? dev->id : 0][event->u.u.type]; + return GetEventFilterMask(dev, event->u.u.type); else if ((evtype = xi2_get_type(event))) - return (1 << (evtype % 8)); + return GetXI2EventFilterMask(evtype); ErrorF("[dix] Unknown event type %d. No filter\n", event->u.u.type); return 0; } /** + * Return the single byte of the device's XI2 mask that contains the mask + * for the event_type. + */ +static int +GetXI2MaskByte(unsigned char xi2mask[][XI2MASKSIZE], DeviceIntPtr dev, int event_type) +{ + int byte = GetXI2EventFilterOffset(event_type); + return xi2mask[dev->id][byte] | + xi2mask[XIAllDevices][byte] | + (IsMaster(dev) ? xi2mask[XIAllMasterDevices][byte] : 0); +} + + +/** * Return the windows complete XI2 mask for the given XI2 event type. */ Mask @@ -452,9 +484,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) evtype = ((xGenericEvent*)ev)->evtype; filter = GetEventFilter(dev, ev); - return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) || - inputMasks->xi2mask[XIAllDevices][evtype/8] || - (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev))); + return (GetXI2MaskByte(inputMasks->xi2mask, dev, evtype) & filter); } Mask @@ -465,10 +495,7 @@ GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ if ((evtype = xi2_get_type(event))) { - int byte = evtype / 8; - return (other->xi2mask[dev->id][byte] | - other->xi2mask[XIAllDevices][byte] | - (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); + return GetXI2MaskByte(other->xi2mask, dev, evtype); } else if (core_get_type(event) != 0) return other->mask[XIAllDevices]; else @@ -680,9 +707,7 @@ ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) BoxRec box; int x = *px, y = *py; int incx = 1, incy = 1; - SpritePtr pSprite; - pSprite = pDev->spriteInfo->sprite; if (RegionContainsPoint(shape, x, y, &box)) return; box = *RegionExtents(shape); @@ -2478,44 +2503,45 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) int filter = 0; int type; OtherInputMasks *inputMasks = wOtherInputMasks(win); - xEvent ev; - - /* XXX: this makes me gag */ - type = GetXI2Type(event); - ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/ - ((xGenericEvent*)&ev)->extension = IReqCode; - ((xGenericEvent*)&ev)->evtype = type; - filter = GetEventFilter(dev, &ev); - if (type && inputMasks && - ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) || - ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) || - (inputMasks->xi2mask[dev->id][type/8] & filter))) - rc |= EVENT_XI2_MASK; - - type = GetXIType(event); - ev.u.u.type = type; - filter = GetEventFilter(dev, &ev); - - /* Check for XI mask */ - if (type && inputMasks && - (inputMasks->deliverableEvents[dev->id] & filter) && - (inputMasks->inputEvents[dev->id] & filter)) - rc |= EVENT_XI1_MASK; - - /* Check for XI DontPropagate mask */ - if (type && inputMasks && - (inputMasks->dontPropagateMask[dev->id] & filter)) - rc |= EVENT_DONT_PROPAGATE_MASK; - - /* Check for core mask */ - type = GetCoreType(event); - if (type && (win->deliverableEvents & filter) && - ((wOtherEventMasks(win) | win->eventMask) & filter)) - rc |= EVENT_CORE_MASK; - - /* Check for core DontPropagate mask */ - if (type && (filter & wDontPropagateMask(win))) - rc |= EVENT_DONT_PROPAGATE_MASK; + + if ((type = GetXI2Type(event)) != 0) + { + filter = GetXI2EventFilterMask(type); + + if (inputMasks && + (GetXI2MaskByte(inputMasks->xi2mask, dev, type) & filter)) + rc |= EVENT_XI2_MASK; + } + + if ((type = GetXIType(event)) != 0) + { + filter = GetEventFilterMask(dev, type); + + /* Check for XI mask */ + if (inputMasks && + (inputMasks->deliverableEvents[dev->id] & filter) && + (inputMasks->inputEvents[dev->id] & filter)) + rc |= EVENT_XI1_MASK; + + /* Check for XI DontPropagate mask */ + if (inputMasks && (inputMasks->dontPropagateMask[dev->id] & filter)) + rc |= EVENT_DONT_PROPAGATE_MASK; + + } + + if ((type = GetCoreType(event)) != 0) + { + filter = GetEventFilterMask(dev, type); + + /* Check for core mask */ + if ((win->deliverableEvents & filter) && + ((wOtherEventMasks(win) | win->eventMask) & filter)) + rc |= EVENT_CORE_MASK; + + /* Check for core DontPropagate mask */ + if (filter & wDontPropagateMask(win)) + rc |= EVENT_DONT_PROPAGATE_MASK; + } return rc; } @@ -3351,16 +3377,21 @@ XineramaWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; - SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; + DeviceIntPtr dev; + SpritePtr pSprite; REQUEST(xWarpPointerReq); - if (stuff->dstWid != None) { rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess); if (rc != Success) return rc; } + + /* Post through the XTest device */ + dev = PickPointer(client); + dev = GetXTestDevice(dev); + pSprite = dev->spriteInfo->sprite; x = pSprite->hotPhys.x; y = pSprite->hotPhys.y; @@ -3410,9 +3441,9 @@ XineramaWarpPointer(ClientPtr client) else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) - ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); + ConfineToShape(dev, pSprite->hotShape, &x, &y); - XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); + XineramaSetCursorPosition(dev, x, y, TRUE); return Success; } @@ -3430,7 +3461,7 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; - DeviceIntPtr dev, tmp; + DeviceIntPtr dev, tmp, xtest_dev = NULL; SpritePtr pSprite; REQUEST(xWarpPointerReq); @@ -3443,11 +3474,13 @@ ProcWarpPointer(ClientPtr client) rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); if (rc != Success) return rc; + if (IsXTestDevice(tmp, dev)) + xtest_dev = tmp; } } - if (dev->lastSlave) - dev = dev->lastSlave; + /* Use the XTest device to actually move the pointer */ + dev = xtest_dev; pSprite = dev->spriteInfo->sprite; #ifdef PANORAMIX @@ -3678,7 +3711,7 @@ CheckPassiveGrabsOnWindow( if (tempGrab.type < GenericEvent) { grab->device = device; - grab->modifierDevice = GetPairedDevice(device); + grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD); } for (other = inputInfo.devices; other; other = other->next) @@ -4063,9 +4096,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, if (rc == Success) { int evtype = xi2_get_type(xi2); - mask = grab->xi2mask[XIAllDevices][evtype/8] | - grab->xi2mask[XIAllMasterDevices][evtype/8] | - grab->xi2mask[thisDev->id][evtype/8]; + mask = GetXI2MaskByte(grab->xi2mask, thisDev, evtype); /* try XI2 event */ FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE); /* XXX: XACE */ @@ -4544,9 +4575,7 @@ DeviceEnterLeaveEvent( if (grab) { Mask mask; - mask = grab->xi2mask[XIAllDevices][type/8] | - grab->xi2mask[XIAllMasterDevices][type/8] | - grab->xi2mask[mouse->id][type/8]; + mask = GetXI2MaskByte(grab->xi2mask, mouse, type); TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, filter, grab); } else { @@ -4765,7 +4794,6 @@ ProcGrabPointer(ClientPtr client) WindowPtr confineTo; CursorPtr oldCursor; REQUEST(xGrabPointerReq); - TimeStamp time; int rc; REQUEST_SIZE_MATCH(xGrabPointerReq); @@ -4811,7 +4839,6 @@ ProcGrabPointer(ClientPtr client) if (oldCursor && rep.status == GrabSuccess) FreeCursor (oldCursor, (Cursor)0); - time = ClientTimeToServerTime(stuff->time); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; @@ -5224,6 +5251,8 @@ CloseDownEvents(void) InputEventList = NULL; } +#define SEND_EVENT_BIT 0x80 + /** * Server-side protocol handling for SendEvent request. * @@ -5241,6 +5270,16 @@ ProcSendEvent(ClientPtr client) REQUEST_SIZE_MATCH(xSendEventReq); + /* libXext and other extension libraries may set the bit indicating + * that this event came from a SendEvent request so remove it + * since otherwise the event type may fail the range checks + * and cause an invalid BadValue error to be returned. + * + * This is safe to do since we later add the SendEvent bit (0x80) + * back in once we send the event to the client */ + + stuff->event.u.u.type &= ~(SEND_EVENT_BIT); + /* The client's event type must be a core event type or one defined by an extension. */ @@ -5298,7 +5337,7 @@ ProcSendEvent(ClientPtr client) client->errorValue = stuff->propagate; return BadValue; } - stuff->event.u.u.type |= 0x80; + stuff->event.u.u.type |= SEND_EVENT_BIT; if (stuff->propagate) { for (;pWin; pWin = pWin->parent) @@ -5360,7 +5399,7 @@ ProcUngrabKey(ClientPtr client) tempGrab.window = pWin; tempGrab.modifiersDetail.exact = stuff->modifiers; tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = GetPairedDevice(keybd); + tempGrab.modifierDevice = keybd; tempGrab.type = KeyPress; tempGrab.grabtype = GRABTYPE_CORE; tempGrab.detail.exact = stuff->key; diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index a12462a4a..be2840c47 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -154,17 +154,6 @@ key_autorepeats(DeviceIntPtr pDev, int key_code) } static void -init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) -{ - memset(event, 0, sizeof(DeviceEvent)); - event->header = ET_Internal; - event->length = sizeof(DeviceEvent); - event->time = ms; - event->deviceid = dev->id; - event->sourceid = dev->id; -} - -static void init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) { memset(event, 0, sizeof(RawDeviceEvent)); @@ -414,7 +403,6 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, Time current; /* The size of a single motion event. */ int size; - int dflt; AxisInfo from, *to; /* for scaling */ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ INT16 *corebuf; @@ -502,13 +490,6 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, else if (j == 1 && (from.max_value < from.min_value)) from.max_value = pScreen->height; - if (j == 0 && (to->max_value < to->min_value)) - dflt = pScreen->width; - else if (j == 1 && (to->max_value < to->min_value)) - dflt = pScreen->height; - else - dflt = 0; - /* scale from stored range into current range */ coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0); memcpy(ocbuf, &coord, sizeof(INT32)); @@ -1014,7 +995,7 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); event = &events->device_event; - init_event(pDev, event, ms); + init_device_event(event, pDev, ms); event->detail.key = key_code; if (type == KeyPress) { @@ -1236,7 +1217,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons clipValuators(pDev, &mask); event = &events->device_event; - init_event(pDev, event, ms); + init_device_event(event, pDev, ms); if (type == MotionNotify) { event->type = ET_Motion; @@ -1329,7 +1310,7 @@ GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const Val events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); event = &events->device_event; - init_event(pDev, event, GetTimeInMillis()); + init_device_event(event, pDev, GetTimeInMillis()); event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; clipValuators(pDev, &mask); @@ -1365,7 +1346,7 @@ PostSyntheticMotion(DeviceIntPtr pDev, #endif memset(&ev, 0, sizeof(DeviceEvent)); - init_event(pDev, &ev, time); + init_device_event(&ev, pDev, time); ev.root_x = x; ev.root_y = y; ev.type = ET_Motion; diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c index 85ca9eee0..c28356d9b 100644 --- a/xorg-server/dix/grabs.c +++ b/xorg-server/dix/grabs.c @@ -479,7 +479,7 @@ AddPassiveGrabToList(ClientPtr client, GrabPtr pGrab) for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) { - if (GrabMatchesSecond(pGrab, grab, FALSE)) + if (GrabMatchesSecond(pGrab, grab, (pGrab->grabtype == GRABTYPE_CORE))) { if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource)) { diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c index 49e175822..7aeb1e516 100644 --- a/xorg-server/dix/inpututils.c +++ b/xorg-server/dix/inpututils.c @@ -584,3 +584,158 @@ void verify_internal_event(const InternalEvent *ev) FatalError("Wrong event type %d. Aborting server\n", ev->any.header); } } + +/** + * Initializes the given event to zero (or default values), for the given + * device. + */ +void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms) +{ + memset(event, 0, sizeof(DeviceEvent)); + event->header = ET_Internal; + event->length = sizeof(DeviceEvent); + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; +} + +/** + * Delete the element with the key from the list, freeing all memory + * associated with the element.. + */ +static void +input_option_free(InputOption *o) +{ + free(o->key); + free(o->value); + free(o); +} + +/* + * Create a new InputOption with the key/value pair provided. + * If a list is provided, the new options is added to the list and the list + * is returned. + * + * If a new option is added to a list that already contains that option, the + * previous option is overwritten. + * + * @param list The list to add to. + * @param key Option key, will be copied. + * @param value Option value, will be copied. + * + * @return If list is not NULL, the list with the new option added. If list + * is NULL, a new option list with one element. On failure, NULL is + * returned. + */ +InputOption* +input_option_new(InputOption* list, const char *key, const char *value) +{ + InputOption *opt = NULL; + + if (!key) + return NULL; + + if (list) + { + nt_list_for_each_entry(opt, list, next) + { + if (strcmp(input_option_get_key(opt), key) == 0) + { + input_option_set_value(opt, value); + return list; + } + } + } + + opt = calloc(1, sizeof(InputOption)); + if (!opt) + return NULL; + + nt_list_init(opt, next); + input_option_set_key(opt, key); + input_option_set_value(opt, value); + + if (list) + { + nt_list_append(opt, list, InputOption, next); + return list; + } else + return opt; +} + +InputOption* +input_option_free_element(InputOption *list, const char *key) +{ + InputOption *element; + + nt_list_for_each_entry(element, list, next) { + if (strcmp(input_option_get_key(element), key) == 0) { + nt_list_del(element, list, InputOption, next); + input_option_free(element); + break; + } + } + return list; +} + +/** + * Free the list pointed at by opt. + */ +void +input_option_free_list(InputOption **opt) +{ + InputOption *element, *tmp; + + nt_list_for_each_entry_safe(element, tmp, *opt, next) { + nt_list_del(element, *opt, InputOption, next); + input_option_free(element); + } + *opt = NULL; +} + + +/** + * Find the InputOption with the given option name. + * + * @return The InputOption or NULL if not present. + */ +InputOption* +input_option_find(InputOption *list, const char *key) +{ + InputOption *element; + + nt_list_for_each_entry(element, list, next) { + if (strcmp(input_option_get_key(element), key) == 0) + return element; + } + + return NULL; +} + +const char* +input_option_get_key(const InputOption *opt) +{ + return opt->key; +} + +const char* +input_option_get_value(const InputOption *opt) +{ + return opt->value; +} + +void +input_option_set_key(InputOption *opt, const char *key) +{ + free(opt->key); + if (key) + opt->key = strdup(key); +} + +void +input_option_set_value(InputOption *opt, const char *value) +{ + free(opt->value); + if (value) + opt->value = strdup(value); +} diff --git a/xorg-server/hw/xfree86/common/Makefile.am b/xorg-server/hw/xfree86/common/Makefile.am index c031d4be3..23ddb5c34 100644 --- a/xorg-server/hw/xfree86/common/Makefile.am +++ b/xorg-server/hw/xfree86/common/Makefile.am @@ -51,7 +51,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \ xf86PciInfo.h xf86Priv.h xf86Privstr.h \ xf86cmap.h xf86fbman.h xf86str.h xf86Xinput.h xisb.h \ $(XVSDKINCS) $(XF86VMODE_SDK) xorgVersion.h \ - xf86sbusBus.h xf86VGAarbiter.h + xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h DISTCLEANFILES = xf86Build.h CLEANFILES = $(BUILT_SOURCES) diff --git a/xorg-server/hw/xfree86/common/xf86.h b/xorg-server/hw/xfree86/common/xf86.h index e1e0cd7e0..1b6c9984c 100644 --- a/xorg-server/hw/xfree86/common/xf86.h +++ b/xorg-server/hw/xfree86/common/xf86.h @@ -331,7 +331,7 @@ extern _X_EXPORT DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePt /* xf86Option.c */ -extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts); +extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts); /* xf86RandR.c */ diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index 3aa923a28..e6c4d8f9f 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -1038,6 +1038,45 @@ Bool xf86DRI2Enabled(void) return xf86Info.dri2; } +/** + * Search for the pInfo in the null-terminated list given and remove (and + * free) it if present. All other devices are moved forward. + */ +static void +freeDevice(InputInfoPtr *list, InputInfoPtr pInfo) +{ + InputInfoPtr *devs; + + for (devs = list; devs && *devs; devs++) { + if (*devs == pInfo) { + free(*devs); + for (; devs && *devs; devs++) + devs[0] = devs[1]; + break; + } + } +} + +/** + * Append pInfo to the null-terminated list, allocating space as necessary. + * pInfo is used as the last element. + */ +static InputInfoPtr* +addDevice(InputInfoPtr *list, InputInfoPtr pInfo) +{ + InputInfoPtr *devs; + int count = 1; + + for (devs = list; devs && *devs; devs++) + count++; + + list = xnfrealloc(list, (count + 1) * sizeof(InputInfoPtr)); + list[count] = NULL; + + list[count - 1] = pInfo; + return list; +} + /* * Locate the core input devices. These can be specified/located in * the following ways, in order of priority: @@ -1061,12 +1100,10 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) const char *pointerMsg = NULL, *keyboardMsg = NULL; InputInfoPtr *devs, /* iterator */ indp; - InputInfoRec Pointer = {}, Keyboard = {}; + InputInfoPtr Pointer, Keyboard; XF86ConfInputPtr confInput; XF86ConfInputRec defPtr, defKbd; - int count = 0; MessageType from = X_DEFAULT; - int found = 0; const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse", "void", NULL }; @@ -1081,25 +1118,14 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) xf86CheckBoolOption(indp->options, "CorePointer", FALSE)) { if (!corePointer) { corePointer = indp; - } else { - xf86ReplaceBoolOption(indp->options, "CorePointer", FALSE); - xf86Msg(X_WARNING, "Duplicate core pointer devices. " - "Removing core pointer attribute from \"%s\"\n", - indp->name); } } if (indp->options && xf86CheckBoolOption(indp->options, "CoreKeyboard", FALSE)) { if (!coreKeyboard) { coreKeyboard = indp; - } else { - xf86ReplaceBoolOption(indp->options, "CoreKeyboard", FALSE); - xf86Msg(X_WARNING, "Duplicate core keyboard devices. " - "Removing core keyboard attribute from \"%s\"\n", - indp->name); } } - count++; } confInput = NULL; @@ -1119,18 +1145,9 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) * removed. */ if (corePointer) { - for (devs = servlayoutp->inputs; devs && *devs; devs++) - if (*devs == corePointer) - { - free(*devs); - *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop*/ - break; - } - for (; devs && *devs; devs++) - devs[0] = devs[1]; - count--; + freeDevice(servlayoutp->inputs, corePointer); + corePointer = NULL; } - corePointer = NULL; foundPointer = TRUE; } @@ -1186,67 +1203,23 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) /* Add the core pointer device to the layout, and set it to Core. */ if (foundPointer && confInput) { - foundPointer = configInput(&Pointer, confInput, from); - if (foundPointer) { - count++; - devs = xnfrealloc(servlayoutp->inputs, - (count + 1) * sizeof(InputInfoPtr)); - devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); - Pointer.fd = -1; - *devs[count - 1] = Pointer; - devs[count - 1]->options = - xf86addNewOption(devs[count -1]->options, - xnfstrdup("CorePointer"), NULL); - devs[count] = NULL; - servlayoutp->inputs = devs; + Pointer = xf86AllocateInput(); + if (Pointer) + foundPointer = configInput(Pointer, confInput, from); + if (foundPointer) { + Pointer->options = xf86addNewOption(Pointer->options, + xnfstrdup("CorePointer"), "on"); + servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer); } } if (!foundPointer && xf86Info.forceInputDevices) { /* This shouldn't happen. */ xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n"); + xf86DeleteInput(Pointer, 0); return FALSE; } - /* - * always synthesize a 'mouse' section configured to send core - * events, unless a 'void' section is found, in which case the user - * probably wants to run footless. - * - * If you're using an evdev keyboard and expect a default mouse - * section ... deal. - */ - for (devs = servlayoutp->inputs; devs && *devs; devs++) { - const char **driver = mousedrivers; - while(*driver) { - if (!strcmp((*devs)->driver, *driver)) { - found = 1; - break; - } - driver++; - } - } - if (!found && xf86Info.forceInputDevices) { - xf86Msg(X_INFO, "No default mouse found, adding one\n"); - memset(&defPtr, 0, sizeof(defPtr)); - defPtr.inp_identifier = strdup("<default pointer>"); - defPtr.inp_driver = strdup("mouse"); - confInput = &defPtr; - foundPointer = configInput(&Pointer, confInput, from); - if (foundPointer) { - count++; - devs = xnfrealloc(servlayoutp->inputs, - (count + 1) * sizeof(InputInfoPtr)); - devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); - Pointer.fd = -1; - *devs[count - 1] = Pointer; - devs[count - 1]->options = - xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL); - devs[count] = NULL; - servlayoutp->inputs = devs; - } - } - confInput = NULL; /* 1. Check for the -keyboard command line option. */ @@ -1264,18 +1237,9 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) * removed. */ if (coreKeyboard) { - for (devs = servlayoutp->inputs; devs && *devs; devs++) - if (*devs == coreKeyboard) - { - free(*devs); - *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop */ - break; - } - for (; devs && *devs; devs++) - devs[0] = devs[1]; - count--; + freeDevice(servlayoutp->inputs, coreKeyboard); + coreKeyboard = NULL; } - coreKeyboard = NULL; foundKeyboard = TRUE; } @@ -1329,25 +1293,20 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) /* Add the core keyboard device to the layout, and set it to Core. */ if (foundKeyboard && confInput) { - foundKeyboard = configInput(&Keyboard, confInput, from); - if (foundKeyboard) { - count++; - devs = xnfrealloc(servlayoutp->inputs, - (count + 1) * sizeof(InputInfoPtr)); - devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); - Keyboard.fd = -1; - *devs[count - 1] = Keyboard; - devs[count - 1]->options = - xf86addNewOption(devs[count - 1]->options, - xnfstrdup("CoreKeyboard"), NULL); - devs[count] = NULL; - servlayoutp->inputs = devs; + Keyboard = xf86AllocateInput(); + if (Keyboard) + foundKeyboard = configInput(Keyboard, confInput, from); + if (foundKeyboard) { + Keyboard->options = xf86addNewOption(Keyboard->options, + xnfstrdup("CoreKeyboard"), "on"); + servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard); } } if (!foundKeyboard && xf86Info.forceInputDevices) { /* This shouldn't happen. */ xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n"); + xf86DeleteInput(Keyboard, 0); return FALSE; } diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c index 7c76fa8ec..a8aa316ae 100644 --- a/xorg-server/hw/xfree86/common/xf86Helper.c +++ b/xorg-server/hw/xfree86/common/xf86Helper.c @@ -1027,36 +1027,20 @@ xf86EnableDisableFBAccess(int scrnIndex, Bool enable) } } -/* Print driver messages in the standard format */ - -#undef PREFIX_SIZE -#define PREFIX_SIZE 14 - +/* Print driver messages in the standard format of + (<type>) <screen name>(<screen index>): <message> */ void xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, va_list args) { - char *tmpFormat; - /* Prefix the scrnIndex name to the format string. */ if (scrnIndex >= 0 && scrnIndex < xf86NumScreens && - xf86Screens[scrnIndex]->name) { - tmpFormat = malloc(strlen(format) + - strlen(xf86Screens[scrnIndex]->name) + - PREFIX_SIZE + 1); - if (!tmpFormat) - return; - - snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ", - xf86Screens[scrnIndex]->name, scrnIndex); - - strcat(tmpFormat, format); - LogVMessageVerb(type, verb, tmpFormat, args); - free(tmpFormat); - } else + xf86Screens[scrnIndex]->name) + LogHdrMessageVerb(type, verb, format, args, "%s(%d): ", + xf86Screens[scrnIndex]->name, scrnIndex); + else LogVMessageVerb(type, verb, format, args); } -#undef PREFIX_SIZE /* Print driver messages, with verbose level specified directly */ void @@ -1082,20 +1066,23 @@ xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) } /* Print input driver messages in the standard format of - <driver>: <device name>: <message> */ + (<type>) <driver>: <device name>: <message> */ void -xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format, - va_list args) +xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, + const char *format, va_list args) { - char *msg; + const char *driverName = NULL; + const char *deviceName = NULL; - if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format) - == -1) { - LogVMessageVerb(type, verb, "%s", args); - } else { - LogVMessageVerb(type, verb, msg, args); - free(msg); + /* Prefix driver and device names to formatted message. */ + if (dev) { + deviceName = dev->name; + if (dev->drv) + driverName = dev->drv->driverName; } + + LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName, + deviceName); } /* Print input driver message, with verbose level specified directly */ diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c index 93ea333bf..350918dfe 100644 --- a/xorg-server/hw/xfree86/common/xf86Init.c +++ b/xorg-server/hw/xfree86/common/xf86Init.c @@ -80,6 +80,7 @@ #include "xf86Bus.h" #include "xf86VGAarbiter.h" #include "globals.h" +#include "xserver-properties.h" #ifdef DPMSExtension #include <X11/extensions/dpmsconst.h> @@ -654,6 +655,24 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) } } + if (SeatId) { + Atom SeatAtom; + + SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE); + + for (i = 0; i < xf86NumScreens; i++) { + int ret; + + ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex, + SeatAtom, XA_STRING, 8, + strlen(SeatId)+1, SeatId ); + if (ret != Success) { + xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING, + "Failed to register seat property\n"); + } + } + } + /* If a screen uses depth 24, show what the pixmap format is */ for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->depth == 24) { @@ -806,11 +825,10 @@ duplicateDevice(InputInfoPtr pInfo) return dup; } -/* - * InitInput -- - * Initialize all supported input devices. +/** + * Initialize all supported input devices present and referenced in the + * xorg.conf. */ - void InitInput(int argc, char **argv) { diff --git a/xorg-server/hw/xfree86/common/xf86Opt.h b/xorg-server/hw/xfree86/common/xf86Opt.h index 5ce320891..88392dc6d 100644 --- a/xorg-server/hw/xfree86/common/xf86Opt.h +++ b/xorg-server/hw/xfree86/common/xf86Opt.h @@ -1,118 +1,119 @@ -
-/*
- * Copyright (c) 1998-2003 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/* Option handling things that ModuleSetup procs can use */
-
-#ifndef _XF86_OPT_H_
-#define _XF86_OPT_H_
-
-typedef struct {
- double freq;
- int units;
-} OptFrequency;
-
-typedef union {
- unsigned long num;
- char * str;
- double realnum;
- Bool bool;
- OptFrequency freq;
-} ValueUnion;
-
-typedef enum {
- OPTV_NONE = 0,
- OPTV_INTEGER,
- OPTV_STRING, /* a non-empty string */
- OPTV_ANYSTR, /* Any string, including an empty one */
- OPTV_REAL,
- OPTV_BOOLEAN,
- OPTV_PERCENT,
- OPTV_FREQ
-} OptionValueType;
-
-typedef enum {
- OPTUNITS_HZ = 1,
- OPTUNITS_KHZ,
- OPTUNITS_MHZ
-} OptFreqUnits;
-
-typedef struct {
- int token;
- const char* name;
- OptionValueType type;
- ValueUnion value;
- Bool found;
-} OptionInfoRec, *OptionInfoPtr;
-
-extern _X_EXPORT int xf86SetIntOption(pointer optlist, const char *name, int deflt);
-extern _X_EXPORT double xf86SetRealOption(pointer optlist, const char *name, double deflt);
-extern _X_EXPORT char *xf86SetStrOption(pointer optlist, const char *name, char *deflt);
-extern _X_EXPORT int xf86SetBoolOption(pointer list, const char *name, int deflt );
-extern _X_EXPORT double xf86SetPercentOption(pointer list, const char *name, double deflt );
-extern _X_EXPORT int xf86CheckIntOption(pointer optlist, const char *name, int deflt);
-extern _X_EXPORT double xf86CheckRealOption(pointer optlist, const char *name, double deflt);
-extern _X_EXPORT char *xf86CheckStrOption(pointer optlist, const char *name, char *deflt);
-extern _X_EXPORT int xf86CheckBoolOption(pointer list, const char *name, int deflt );
-extern _X_EXPORT double xf86CheckPercentOption(pointer list, const char *name, double deflt );
-extern _X_EXPORT pointer xf86AddNewOption(pointer head, const char *name, const char *val );
-extern _X_EXPORT pointer xf86NewOption(char *name, char *value );
-extern _X_EXPORT pointer xf86NextOption(pointer list );
-extern _X_EXPORT pointer xf86OptionListCreate(const char **options, int count, int used);
-extern _X_EXPORT pointer xf86OptionListMerge(pointer head, pointer tail);
-extern _X_EXPORT pointer xf86OptionListDuplicate(pointer list);
-extern _X_EXPORT void xf86OptionListFree(pointer opt);
-extern _X_EXPORT char *xf86OptionName(pointer opt);
-extern _X_EXPORT char *xf86OptionValue(pointer opt);
-extern _X_EXPORT void xf86OptionListReport(pointer parm);
-extern _X_EXPORT pointer xf86FindOption(pointer options, const char *name);
-extern _X_EXPORT char *xf86FindOptionValue(pointer options, const char *name);
-extern _X_EXPORT void xf86MarkOptionUsed(pointer option);
-extern _X_EXPORT void xf86MarkOptionUsedByName(pointer options, const char *name);
-extern _X_EXPORT Bool xf86CheckIfOptionUsed(pointer option);
-extern _X_EXPORT Bool xf86CheckIfOptionUsedByName(pointer options, const char *name);
-extern _X_EXPORT void xf86ShowUnusedOptions(int scrnIndex, pointer options);
-extern _X_EXPORT void xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo);
-extern _X_EXPORT OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table, int token);
-extern _X_EXPORT const char *xf86TokenToOptName(const OptionInfoRec *table, int token);
-extern _X_EXPORT Bool xf86IsOptionSet(const OptionInfoRec *table, int token);
-extern _X_EXPORT char *xf86GetOptValString(const OptionInfoRec *table, int token);
-extern _X_EXPORT Bool xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value);
-extern _X_EXPORT Bool xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value);
-extern _X_EXPORT Bool xf86GetOptValReal(const OptionInfoRec *table, int token, double *value);
-extern _X_EXPORT Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
- OptFreqUnits expectedUnits, double *value);
-extern _X_EXPORT Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value);
-extern _X_EXPORT Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def);
-extern _X_EXPORT int xf86NameCmp(const char *s1, const char *s2);
-extern _X_EXPORT char *xf86NormalizeName(const char *s);
-extern _X_EXPORT pointer xf86ReplaceIntOption(pointer optlist, const char *name, const int val);
-extern _X_EXPORT pointer xf86ReplaceRealOption(pointer optlist, const char *name, const double val);
-extern _X_EXPORT pointer xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val);
-extern _X_EXPORT pointer xf86ReplacePercentOption(pointer optlist, const char *name, const double val);
-extern _X_EXPORT pointer xf86ReplaceStrOption(pointer optlist, const char *name, const char* val);
-#endif
+ +/* + * Copyright (c) 1998-2003 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* Option handling things that ModuleSetup procs can use */ + +#ifndef _XF86_OPT_H_ +#define _XF86_OPT_H_ +#include "xf86Optionstr.h" + +typedef struct { + double freq; + int units; +} OptFrequency; + +typedef union { + unsigned long num; + char * str; + double realnum; + Bool bool; + OptFrequency freq; +} ValueUnion; + +typedef enum { + OPTV_NONE = 0, + OPTV_INTEGER, + OPTV_STRING, /* a non-empty string */ + OPTV_ANYSTR, /* Any string, including an empty one */ + OPTV_REAL, + OPTV_BOOLEAN, + OPTV_PERCENT, + OPTV_FREQ +} OptionValueType; + +typedef enum { + OPTUNITS_HZ = 1, + OPTUNITS_KHZ, + OPTUNITS_MHZ +} OptFreqUnits; + +typedef struct { + int token; + const char* name; + OptionValueType type; + ValueUnion value; + Bool found; +} OptionInfoRec, *OptionInfoPtr; + +extern _X_EXPORT int xf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt); +extern _X_EXPORT double xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt); +extern _X_EXPORT char *xf86SetStrOption(XF86OptionPtr optlist, const char *name, char *deflt); +extern _X_EXPORT int xf86SetBoolOption(XF86OptionPtr list, const char *name, int deflt ); +extern _X_EXPORT double xf86SetPercentOption(XF86OptionPtr list, const char *name, double deflt ); +extern _X_EXPORT int xf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt); +extern _X_EXPORT double xf86CheckRealOption(XF86OptionPtr optlist, const char *name, double deflt); +extern _X_EXPORT char *xf86CheckStrOption(XF86OptionPtr optlist, const char *name, char *deflt); +extern _X_EXPORT int xf86CheckBoolOption(XF86OptionPtr list, const char *name, int deflt ); +extern _X_EXPORT double xf86CheckPercentOption(XF86OptionPtr list, const char *name, double deflt ); +extern _X_EXPORT XF86OptionPtr xf86AddNewOption(XF86OptionPtr head, const char *name, const char *val ); +extern _X_EXPORT XF86OptionPtr xf86NewOption(char *name, char *value ); +extern _X_EXPORT XF86OptionPtr xf86NextOption(XF86OptionPtr list ); +extern _X_EXPORT XF86OptionPtr xf86OptionListCreate(const char **options, int count, int used); +extern _X_EXPORT XF86OptionPtr xf86OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail); +extern _X_EXPORT XF86OptionPtr xf86OptionListDuplicate(XF86OptionPtr list); +extern _X_EXPORT void xf86OptionListFree(XF86OptionPtr opt); +extern _X_EXPORT char *xf86OptionName(XF86OptionPtr opt); +extern _X_EXPORT char *xf86OptionValue(XF86OptionPtr opt); +extern _X_EXPORT void xf86OptionListReport(XF86OptionPtr parm); +extern _X_EXPORT XF86OptionPtr xf86FindOption(XF86OptionPtr options, const char *name); +extern _X_EXPORT char *xf86FindOptionValue(XF86OptionPtr options, const char *name); +extern _X_EXPORT void xf86MarkOptionUsed(XF86OptionPtr option); +extern _X_EXPORT void xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name); +extern _X_EXPORT Bool xf86CheckIfOptionUsed(XF86OptionPtr option); +extern _X_EXPORT Bool xf86CheckIfOptionUsedByName(XF86OptionPtr options, const char *name); +extern _X_EXPORT void xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr options); +extern _X_EXPORT void xf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo); +extern _X_EXPORT OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table, int token); +extern _X_EXPORT const char *xf86TokenToOptName(const OptionInfoRec *table, int token); +extern _X_EXPORT Bool xf86IsOptionSet(const OptionInfoRec *table, int token); +extern _X_EXPORT char *xf86GetOptValString(const OptionInfoRec *table, int token); +extern _X_EXPORT Bool xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value); +extern _X_EXPORT Bool xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value); +extern _X_EXPORT Bool xf86GetOptValReal(const OptionInfoRec *table, int token, double *value); +extern _X_EXPORT Bool xf86GetOptValFreq(const OptionInfoRec *table, int token, + OptFreqUnits expectedUnits, double *value); +extern _X_EXPORT Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value); +extern _X_EXPORT Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def); +extern _X_EXPORT int xf86NameCmp(const char *s1, const char *s2); +extern _X_EXPORT char *xf86NormalizeName(const char *s); +extern _X_EXPORT XF86OptionPtr xf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val); +extern _X_EXPORT XF86OptionPtr xf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val); +extern _X_EXPORT XF86OptionPtr xf86ReplaceBoolOption(XF86OptionPtr optlist, const char *name, const Bool val); +extern _X_EXPORT XF86OptionPtr xf86ReplacePercentOption(XF86OptionPtr optlist, const char *name, const double val); +extern _X_EXPORT XF86OptionPtr xf86ReplaceStrOption(XF86OptionPtr optlist, const char *name, const char* val); +#endif diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c index a3a836fc1..73b6573f1 100644 --- a/xorg-server/hw/xfree86/common/xf86Option.c +++ b/xorg-server/hw/xfree86/common/xf86Option.c @@ -40,11 +40,12 @@ #include <X11/X.h> #include "os.h" #include "xf86.h" +#include "xf86Opt.h" #include "xf86Xinput.h" #include "xf86Optrec.h" #include "xf86Parser.h" -static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, +static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p, Bool markUsed); /* @@ -66,7 +67,7 @@ static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, */ void -xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts) +xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts) { XF86OptionPtr tmp; XF86OptionPtr extras = (XF86OptionPtr)extraOpts; @@ -140,10 +141,10 @@ xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts) * Duplicate the option list passed in. The returned pointer will be a newly * allocated option list and must be freed by the caller. */ -pointer -xf86OptionListDuplicate(pointer options) +XF86OptionPtr +xf86OptionListDuplicate(XF86OptionPtr options) { - pointer o = NULL; + XF86OptionPtr o = NULL; while (options) { @@ -158,7 +159,7 @@ xf86OptionListDuplicate(pointer options) /* Created for new XInput stuff -- essentially extensions to the parser */ static int -LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed) +LookupIntOption(XF86OptionPtr optlist, const char *name, int deflt, Bool markUsed) { OptionInfoRec o; @@ -171,7 +172,7 @@ LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed) static double -LookupRealOption(pointer optlist, const char *name, double deflt, +LookupRealOption(XF86OptionPtr optlist, const char *name, double deflt, Bool markUsed) { OptionInfoRec o; @@ -185,7 +186,7 @@ LookupRealOption(pointer optlist, const char *name, double deflt, static char * -LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed) +LookupStrOption(XF86OptionPtr optlist, const char *name, char *deflt, Bool markUsed) { OptionInfoRec o; @@ -201,7 +202,7 @@ LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed) static int -LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) +LookupBoolOption(XF86OptionPtr optlist, const char *name, int deflt, Bool markUsed) { OptionInfoRec o; @@ -213,7 +214,7 @@ LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) } static double -LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed) +LookupPercentOption(XF86OptionPtr optlist, const char *name, double deflt, Bool markUsed) { OptionInfoRec o; @@ -227,34 +228,34 @@ LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUs /* These xf86Set* functions are intended for use by non-screen specific code */ int -xf86SetIntOption(pointer optlist, const char *name, int deflt) +xf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt) { return LookupIntOption(optlist, name, deflt, TRUE); } double -xf86SetRealOption(pointer optlist, const char *name, double deflt) +xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt) { return LookupRealOption(optlist, name, deflt, TRUE); } char * -xf86SetStrOption(pointer optlist, const char *name, char *deflt) +xf86SetStrOption(XF86OptionPtr optlist, const char *name, char *deflt) { return LookupStrOption(optlist, name, deflt, TRUE); } int -xf86SetBoolOption(pointer optlist, const char *name, int deflt) +xf86SetBoolOption(XF86OptionPtr optlist, const char *name, int deflt) { return LookupBoolOption(optlist, name, deflt, TRUE); } double -xf86SetPercentOption(pointer optlist, const char *name, double deflt) +xf86SetPercentOption(XF86OptionPtr optlist, const char *name, double deflt) { return LookupPercentOption(optlist, name, deflt, TRUE); } @@ -264,35 +265,35 @@ xf86SetPercentOption(pointer optlist, const char *name, double deflt) * as used. */ int -xf86CheckIntOption(pointer optlist, const char *name, int deflt) +xf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt) { return LookupIntOption(optlist, name, deflt, FALSE); } double -xf86CheckRealOption(pointer optlist, const char *name, double deflt) +xf86CheckRealOption(XF86OptionPtr optlist, const char *name, double deflt) { return LookupRealOption(optlist, name, deflt, FALSE); } char * -xf86CheckStrOption(pointer optlist, const char *name, char *deflt) +xf86CheckStrOption(XF86OptionPtr optlist, const char *name, char *deflt) { return LookupStrOption(optlist, name, deflt, FALSE); } int -xf86CheckBoolOption(pointer optlist, const char *name, int deflt) +xf86CheckBoolOption(XF86OptionPtr optlist, const char *name, int deflt) { return LookupBoolOption(optlist, name, deflt, FALSE); } double -xf86CheckPercentOption(pointer optlist, const char *name, double deflt) +xf86CheckPercentOption(XF86OptionPtr optlist, const char *name, double deflt) { return LookupPercentOption(optlist, name, deflt, FALSE); } @@ -300,44 +301,44 @@ xf86CheckPercentOption(pointer optlist, const char *name, double deflt) * addNewOption() has the required property of replacing the option value * if the option is already present. */ -pointer -xf86ReplaceIntOption(pointer optlist, const char *name, const int val) +XF86OptionPtr +xf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val) { char tmp[16]; sprintf(tmp,"%i",val); return xf86AddNewOption(optlist,name,tmp); } -pointer -xf86ReplaceRealOption(pointer optlist, const char *name, const double val) +XF86OptionPtr +xf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val) { char tmp[32]; snprintf(tmp,32,"%f",val); return xf86AddNewOption(optlist,name,tmp); } -pointer -xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val) +XF86OptionPtr +xf86ReplaceBoolOption(XF86OptionPtr optlist, const char *name, const Bool val) { return xf86AddNewOption(optlist,name,val?"True":"False"); } -pointer -xf86ReplacePercentOption(pointer optlist, const char *name, const double val) +XF86OptionPtr +xf86ReplacePercentOption(XF86OptionPtr optlist, const char *name, const double val) { char tmp[16]; sprintf(tmp, "%lf%%", val); return xf86AddNewOption(optlist,name,tmp); } -pointer -xf86ReplaceStrOption(pointer optlist, const char *name, const char* val) +XF86OptionPtr +xf86ReplaceStrOption(XF86OptionPtr optlist, const char *name, const char* val) { return xf86AddNewOption(optlist,name,val); } -pointer -xf86AddNewOption(pointer head, const char *name, const char *val) +XF86OptionPtr +xf86AddNewOption(XF86OptionPtr head, const char *name, const char *val) { /* XXX These should actually be allocated in the parser library. */ char *tmp = val ? strdup(val) : NULL; @@ -347,51 +348,51 @@ xf86AddNewOption(pointer head, const char *name, const char *val) } -pointer +XF86OptionPtr xf86NewOption(char *name, char *value) { return xf86newOption(name, value); } -pointer -xf86NextOption(pointer list) +XF86OptionPtr +xf86NextOption(XF86OptionPtr list) { return xf86nextOption(list); } -pointer +XF86OptionPtr xf86OptionListCreate(const char **options, int count, int used) { return xf86optionListCreate(options, count, used); } -pointer -xf86OptionListMerge(pointer head, pointer tail) +XF86OptionPtr +xf86OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail) { return xf86optionListMerge(head, tail); } void -xf86OptionListFree(pointer opt) +xf86OptionListFree(XF86OptionPtr opt) { xf86optionListFree(opt); } char * -xf86OptionName(pointer opt) +xf86OptionName(XF86OptionPtr opt) { return xf86optionName(opt); } char * -xf86OptionValue(pointer opt) +xf86OptionValue(XF86OptionPtr opt) { return xf86optionValue(opt); } void -xf86OptionListReport(pointer parm) +xf86OptionListReport(XF86OptionPtr parm) { XF86OptionPtr opts = parm; @@ -407,30 +408,30 @@ xf86OptionListReport(pointer parm) /* End of XInput-caused section */ -pointer -xf86FindOption(pointer options, const char *name) +XF86OptionPtr +xf86FindOption(XF86OptionPtr options, const char *name) { return xf86findOption(options, name); } char * -xf86FindOptionValue(pointer options, const char *name) +xf86FindOptionValue(XF86OptionPtr options, const char *name) { return xf86findOptionValue(options, name); } void -xf86MarkOptionUsed(pointer option) +xf86MarkOptionUsed(XF86OptionPtr option) { if (option != NULL) - ((XF86OptionPtr)option)->opt_used = TRUE; + option->opt_used = TRUE; } void -xf86MarkOptionUsedByName(pointer options, const char *name) +xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name) { XF86OptionPtr opt; @@ -440,16 +441,16 @@ xf86MarkOptionUsedByName(pointer options, const char *name) } Bool -xf86CheckIfOptionUsed(pointer option) +xf86CheckIfOptionUsed(XF86OptionPtr option) { if (option != NULL) - return ((XF86OptionPtr)option)->opt_used; + return option->opt_used; else return FALSE; } Bool -xf86CheckIfOptionUsedByName(pointer options, const char *name) +xf86CheckIfOptionUsedByName(XF86OptionPtr options, const char *name) { XF86OptionPtr opt; @@ -461,10 +462,8 @@ xf86CheckIfOptionUsedByName(pointer options, const char *name) } void -xf86ShowUnusedOptions(int scrnIndex, pointer options) +xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr opt) { - XF86OptionPtr opt = options; - while (opt) { if (opt->opt_name && !opt->opt_used) { xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n", @@ -482,7 +481,7 @@ GetBoolValue(OptionInfoPtr p, const char *s) } static Bool -ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, +ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p, Bool markUsed) { char *s, *end; @@ -695,7 +694,7 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, void -xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo) +xf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo) { OptionInfoPtr p; diff --git a/xorg-server/hw/xfree86/common/xf86Optionstr.h b/xorg-server/hw/xfree86/common/xf86Optionstr.h new file mode 100644 index 000000000..8cc82d34c --- /dev/null +++ b/xorg-server/hw/xfree86/common/xf86Optionstr.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2011 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. + * + */ + +#ifndef XF86OPTIONSTR_H +#define XF86OPTIONSTR_H + +/* + * all records that need to be linked lists should contain a GenericList as + * their first field. + */ +typedef struct generic_list_rec +{ + void *next; +} +GenericListRec, *GenericListPtr, *glp; + +/* + * All options are stored using this data type. + */ +typedef struct _XF86OptionRec +{ + GenericListRec list; + char *opt_name; + char *opt_val; + int opt_used; + char *opt_comment; +} +XF86OptionRec; + +typedef struct _XF86OptionRec *XF86OptionPtr; + +#endif diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index d22fdc8b9..9fbcba9d5 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -266,6 +266,34 @@ ApplyAccelerationSettings(DeviceIntPtr dev){ } } +static void +ApplyTransformationMatrix(DeviceIntPtr dev) +{ + InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; + char *str; + int rc; + float matrix[9] = {0}; + + if (!dev->valuator) + return; + + str = xf86SetStrOption(pInfo->options, "TransformationMatrix", NULL); + if (!str) + return; + + rc = sscanf(str, "%f %f %f %f %f %f %f %f %f", &matrix[0], &matrix[1], &matrix[2], + &matrix[3], &matrix[4], &matrix[5], &matrix[6], &matrix[7], &matrix[8]); + if (rc != 9) { + xf86Msg(X_ERROR, "%s: invalid format for transformation matrix. Ignoring configuration.\n", + pInfo->name); + return; + } + + XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), + XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 9, matrix, FALSE); +} + /*********************************************************************** * * xf86ProcessCommonOptions -- @@ -276,7 +304,7 @@ ApplyAccelerationSettings(DeviceIntPtr dev){ */ void xf86ProcessCommonOptions(InputInfoPtr pInfo, - pointer list) + XF86OptionPtr list) { if (xf86SetBoolOption(list, "Floating", 0) || !xf86SetBoolOption(list, "AlwaysCore", 1) || @@ -746,7 +774,7 @@ xf86DeleteInput(InputInfoPtr pInp, int flags) } /* - * Apply backend-specific initialization. Invoked after ActiveteDevice(), + * Apply backend-specific initialization. Invoked after ActivateDevice(), * i.e. after the driver successfully completed DEVICE_INIT and the device * is advertised. * @param dev the device @@ -755,6 +783,7 @@ xf86DeleteInput(InputInfoPtr pInp, int flags) static int xf86InputDevicePostInit(DeviceIntPtr dev) { ApplyAccelerationSettings(dev); + ApplyTransformationMatrix(dev); return Success; } @@ -879,35 +908,35 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, if (!pInfo) return BadAlloc; - for (option = options; option; option = option->next) { - if (strcasecmp(option->key, "driver") == 0) { + nt_list_for_each_entry(option, options, next) { + if (strcasecmp(input_option_get_key(option), "driver") == 0) { if (pInfo->driver) { rval = BadRequest; goto unwind; } - pInfo->driver = xstrdup(option->value); + pInfo->driver = xstrdup(input_option_get_value(option)); if (!pInfo->driver) { rval = BadAlloc; goto unwind; } } - if (strcasecmp(option->key, "name") == 0 || - strcasecmp(option->key, "identifier") == 0) { + if (strcasecmp(input_option_get_key(option), "name") == 0 || + strcasecmp(input_option_get_key(option), "identifier") == 0) { if (pInfo->name) { rval = BadRequest; goto unwind; } - pInfo->name = xstrdup(option->value); + pInfo->name = xstrdup(input_option_get_value(option)); if (!pInfo->name) { rval = BadAlloc; goto unwind; } } - if (strcmp(option->key, "_source") == 0 && - (strcmp(option->value, "server/hal") == 0 || - strcmp(option->value, "server/udev") == 0)) { + if (strcmp(input_option_get_key(option), "_source") == 0 && + (strcmp(input_option_get_value(option), "server/hal") == 0 || + strcmp(input_option_get_value(option), "server/udev") == 0)) { is_auto = 1; if (!xf86Info.autoAddDevices) { rval = BadMatch; @@ -916,13 +945,11 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, } } - for (option = options; option; option = option->next) { - /* Steal option key/value strings from the provided list. - * We need those strings, the InputOption list doesn't. */ - pInfo->options = xf86addNewOption(pInfo->options, - option->key, option->value); - option->key = NULL; - option->value = NULL; + nt_list_for_each_entry(option, options, next) { + /* Copy option key/value strings from the provided list */ + pInfo->options = xf86AddNewOption(pInfo->options, + input_option_get_key(option), + input_option_get_value(option)); } /* Apply InputClass settings */ @@ -1348,7 +1375,7 @@ xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, } /* - * Set the valuator values to be in synch with dix/event.c + * Set the valuator values to be in sync with dix/event.c * DefineInitialRootWindow(). */ void diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.h b/xorg-server/hw/xfree86/common/xf86Xinput.h index 84683168c..a4d9e58a5 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.h +++ b/xorg-server/hw/xfree86/common/xf86Xinput.h @@ -1,182 +1,182 @@ -/*
- * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Frederic Lepied not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Frederic Lepied makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-/*
- * Copyright (c) 2000-2002 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-#ifndef _xf86Xinput_h
-#define _xf86Xinput_h
-
-#include "xf86str.h"
-#include "inputstr.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "XIstubs.h"
-
-/* Input device flags */
-#define XI86_ALWAYS_CORE 0x04 /* device always controls the pointer */
-/* the device sends Xinput and core pointer events */
-#define XI86_SEND_CORE_EVENTS XI86_ALWAYS_CORE
-
-/* This holds the input driver entry and module information. */
-typedef struct _InputDriverRec {
- int driverVersion;
- char * driverName;
- void (*Identify)(int flags);
- int (*PreInit)(struct _InputDriverRec *drv,
- struct _InputInfoRec* pInfo, int flags);
- void (*UnInit)(struct _InputDriverRec *drv,
- struct _InputInfoRec *pInfo,
- int flags);
- pointer module;
- char ** default_options;
-} InputDriverRec, *InputDriverPtr;
-
-/* This is to input devices what the ScrnInfoRec is to screens. */
-
-typedef struct _InputInfoRec {
- struct _InputInfoRec *next;
- char * name;
- char * driver;
-
- int flags;
-
- Bool (*device_control)(DeviceIntPtr device, int what);
- void (*read_input)(struct _InputInfoRec *local);
- int (*control_proc)(struct _InputInfoRec *local,
- xDeviceCtl *control);
- int (*switch_mode)(ClientPtr client, DeviceIntPtr dev,
- int mode);
- int (*set_device_valuators)
- (struct _InputInfoRec *local,
- int *valuators, int first_valuator,
- int num_valuators);
-
- int fd;
- DeviceIntPtr dev;
- pointer private;
- char * type_name;
- InputDriverPtr drv;
- pointer module;
- pointer options;
- InputAttributes *attrs;
-} *InputInfoPtr;
-
-/* xf86Globals.c */
-extern InputInfoPtr xf86InputDevs;
-
-/* xf86Xinput.c */
-extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute,
- int first_valuator, int num_valuators, ...);
-extern _X_EXPORT void xf86PostMotionEventP(DeviceIntPtr device, int is_absolute,
- int first_valuator, int num_valuators, const int *valuators);
-extern _X_EXPORT void xf86PostMotionEventM(DeviceIntPtr device, int is_absolute,
- const ValuatorMask *mask);
-extern _X_EXPORT void xf86PostProximityEvent(DeviceIntPtr device, int is_in,
- int first_valuator, int num_valuators, ...);
-extern _X_EXPORT void xf86PostProximityEventP(DeviceIntPtr device, int is_in, int first_valuator,
- int num_valuators, const int *valuators);
-extern _X_EXPORT void xf86PostProximityEventM(DeviceIntPtr device, int is_in,
- const ValuatorMask *mask);
-extern _X_EXPORT void xf86PostButtonEvent(DeviceIntPtr device, int is_absolute, int button,
- int is_down, int first_valuator, int num_valuators,
- ...);
-extern _X_EXPORT void xf86PostButtonEventP(DeviceIntPtr device, int is_absolute, int button,
- int is_down, int first_valuator, int num_valuators,
- const int *valuators);
-extern _X_EXPORT void xf86PostButtonEventM(DeviceIntPtr device, int is_absolute, int button,
- int is_down, const ValuatorMask *mask);
-extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down,
- int is_absolute, int first_valuator, int num_valuators,
- ...);
-extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down,
- int is_absolute, const ValuatorMask *mask);
-extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down,
- int is_absolute, int first_valuator, int num_valuators,
- const int *valuators);
-extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code,
- int is_down);
-extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
-extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);
-extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y);
-extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, pointer options);
-extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
- int maxval, int resolution, int min_res,
- int max_res, int mode);
-extern _X_EXPORT void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
-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);
-/* not exported */
-int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
-InputInfoPtr xf86AllocateInput(void);
-
-/* xf86Helper.c */
-extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
-extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex);
-extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
-extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name);
-extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags);
-extern _X_EXPORT void xf86MotionHistoryAllocate(InputInfoPtr pInfo);
-extern _X_EXPORT void xf86IDrvMsgVerb(InputInfoPtr dev,
- MessageType type, int verb,
- const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5);
-extern _X_EXPORT void xf86IDrvMsg(InputInfoPtr dev,
- MessageType type,
- const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
-extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev,
- MessageType type,
- int verb,
- const char *format,
- va_list args);
-
-/* xf86Option.c */
-extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts);
-
-#endif /* _xf86Xinput_h */
+/* + * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Frederic Lepied not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Frederic Lepied makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* + * Copyright (c) 2000-2002 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +#ifndef _xf86Xinput_h +#define _xf86Xinput_h + +#include "xf86str.h" +#include "inputstr.h" +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "XIstubs.h" + +/* Input device flags */ +#define XI86_ALWAYS_CORE 0x04 /* device always controls the pointer */ +/* the device sends Xinput and core pointer events */ +#define XI86_SEND_CORE_EVENTS XI86_ALWAYS_CORE + +/* This holds the input driver entry and module information. */ +typedef struct _InputDriverRec { + int driverVersion; + char * driverName; + void (*Identify)(int flags); + int (*PreInit)(struct _InputDriverRec *drv, + struct _InputInfoRec* pInfo, int flags); + void (*UnInit)(struct _InputDriverRec *drv, + struct _InputInfoRec *pInfo, + int flags); + pointer module; + char ** default_options; +} InputDriverRec, *InputDriverPtr; + +/* This is to input devices what the ScrnInfoRec is to screens. */ + +typedef struct _InputInfoRec { + struct _InputInfoRec *next; + char * name; + char * driver; + + int flags; + + Bool (*device_control)(DeviceIntPtr device, int what); + void (*read_input)(struct _InputInfoRec *local); + int (*control_proc)(struct _InputInfoRec *local, + xDeviceCtl *control); + int (*switch_mode)(ClientPtr client, DeviceIntPtr dev, + int mode); + int (*set_device_valuators) + (struct _InputInfoRec *local, + int *valuators, int first_valuator, + int num_valuators); + + int fd; + DeviceIntPtr dev; + pointer private; + char * type_name; + InputDriverPtr drv; + pointer module; + XF86OptionPtr options; + InputAttributes *attrs; +} *InputInfoPtr; + +/* xf86Globals.c */ +extern InputInfoPtr xf86InputDevs; + +/* xf86Xinput.c */ +extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute, + int first_valuator, int num_valuators, ...); +extern _X_EXPORT void xf86PostMotionEventP(DeviceIntPtr device, int is_absolute, + int first_valuator, int num_valuators, const int *valuators); +extern _X_EXPORT void xf86PostMotionEventM(DeviceIntPtr device, int is_absolute, + const ValuatorMask *mask); +extern _X_EXPORT void xf86PostProximityEvent(DeviceIntPtr device, int is_in, + int first_valuator, int num_valuators, ...); +extern _X_EXPORT void xf86PostProximityEventP(DeviceIntPtr device, int is_in, int first_valuator, + int num_valuators, const int *valuators); +extern _X_EXPORT void xf86PostProximityEventM(DeviceIntPtr device, int is_in, + const ValuatorMask *mask); +extern _X_EXPORT void xf86PostButtonEvent(DeviceIntPtr device, int is_absolute, int button, + int is_down, int first_valuator, int num_valuators, + ...); +extern _X_EXPORT void xf86PostButtonEventP(DeviceIntPtr device, int is_absolute, int button, + int is_down, int first_valuator, int num_valuators, + const int *valuators); +extern _X_EXPORT void xf86PostButtonEventM(DeviceIntPtr device, int is_absolute, int button, + int is_down, const ValuatorMask *mask); +extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down, + int is_absolute, int first_valuator, int num_valuators, + ...); +extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down, + int is_absolute, const ValuatorMask *mask); +extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down, + int is_absolute, int first_valuator, int num_valuators, + const int *valuators); +extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code, + int is_down); +extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void); +extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min); +extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y); +extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, XF86OptionPtr options); +extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, + int maxval, int resolution, int min_res, + int max_res, int mode); +extern _X_EXPORT void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum); +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); +/* not exported */ +int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto); +InputInfoPtr xf86AllocateInput(void); + +/* xf86Helper.c */ +extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags); +extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex); +extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name); +extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name); +extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags); +extern _X_EXPORT void xf86MotionHistoryAllocate(InputInfoPtr pInfo); +extern _X_EXPORT void xf86IDrvMsgVerb(InputInfoPtr dev, + MessageType type, int verb, + const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5); +extern _X_EXPORT void xf86IDrvMsg(InputInfoPtr dev, + MessageType type, + const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4); +extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev, + MessageType type, + int verb, + const char *format, + va_list args); + +/* xf86Option.c */ +extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts); + +#endif /* _xf86Xinput_h */ diff --git a/xorg-server/hw/xfree86/doc/ddxDesign.xml b/xorg-server/hw/xfree86/doc/ddxDesign.xml index 02909602c..bc25c56d8 100644 --- a/xorg-server/hw/xfree86/doc/ddxDesign.xml +++ b/xorg-server/hw/xfree86/doc/ddxDesign.xml @@ -3175,7 +3175,7 @@ would not need to use these directly. <blockquote><para> <programlisting> - pointer xf86FindOption(pointer options, const char *name); + XF86OptionPtr xf86FindOption(XF86OptionPtr options, const char *name); </programlisting> <blockquote><para> Takes a list of options and an option name, and returns a handle @@ -3187,7 +3187,7 @@ would not need to use these directly. <blockquote><para> <programlisting> - char *xf86FindOptionValue(pointer options, const char *name); + char *xf86FindOptionValue(XF86OptionPtr options, const char *name); </programlisting> <blockquote><para> Takes a list of options and an option name, and returns the value @@ -3201,7 +3201,7 @@ would not need to use these directly. <blockquote><para> <programlisting> - void xf86MarkOptionUsed(pointer option); + void xf86MarkOptionUsed(XF86OptionPtr option); </programlisting> <blockquote><para> Takes a handle for an option, and marks that option as used. @@ -3211,7 +3211,7 @@ would not need to use these directly. <blockquote><para> <programlisting> - void xf86MarkOptionUsedByName(pointer options, const char *name); + void xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name); </programlisting> <blockquote><para> Takes a list of options and an option name and marks the first @@ -3225,7 +3225,7 @@ Next, the higher level functions that most drivers would use. </para> <blockquote><para> <programlisting> - void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts); + void xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts); </programlisting> <blockquote><para> Collect the options from each of the config file sections used by @@ -3245,7 +3245,7 @@ Next, the higher level functions that most drivers would use. <blockquote><para> <programlisting> - void xf86ProcessOptions(int scrnIndex, pointer options, + void xf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo); </programlisting> <blockquote><para> @@ -3354,7 +3354,7 @@ Next, the higher level functions that most drivers would use. <blockquote><para> <programlisting> - void xf86ShowUnusedOptions(int scrnIndex, pointer options); + void xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr options); </programlisting> <blockquote><para> Prints out warning messages for each option in the list of options diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 8f14efb64..62c491cb2 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -942,7 +942,18 @@ is equivalent to This option controls the startup behavior only, a device may be reattached or set floating at runtime. -.PP +.TP 7 +.BI "Option \*qTransformationMatrix\*q \*q" a " " b " " c " " d " " e " " f " " g " " h " " i \*q +Specifies the 3x3 transformation matrix for absolute input devices. The +input device will be bound to the area given in the matrix. In most +configurations, "a" and "e" specify the width and height of the area the +device is bound to, and "c" and "f" specify the x and y offset of the area. +The value range is 0 to 1, where 1 represents the width or height of all +root windows together, 0.5 represents half the area, etc. The values +represent a 3x3 matrix, with the first, second and third group of three +values representing the first, second and third row of the matrix, +respectively. The identity matrix is "1 0 0 0 1 0 0 0 1". +.SS POINTER ACCELERATION For pointing devices, the following options control how the pointer is accelerated or decelerated with respect to physical device motion. Most of these can be adjusted at runtime, see the xinput(1) man page for details. Only @@ -1432,7 +1443,7 @@ driver plus the identifier of a monitor section, one associates a monitor section with an output by adding an option to the Device section in the following format: -.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q +.BI "Option \*qMonitor-" outputname "\*q \*q" monitorsection \*q (for example, .B Option \*qMonitor-VGA\*q \*qVGA monitor\*q @@ -1448,7 +1459,7 @@ modes available. When modes are specified explicitly in the .B Monitor section (with the -.BR Modes , +.BR Mode , .BR ModeLine , or .B UseModes @@ -1597,7 +1608,7 @@ mentioned above doubles this value. This entry is a more compact version of the .B Mode entry, and it also can be used to specify video modes for the monitor. -is a single line format for specifying video modes. +This is a single line format for specifying video modes. In most cases this isn't necessary because the built\-in set of VESA standard modes will be sufficient. .PP @@ -1652,61 +1663,61 @@ The and .B VScan options mentioned above in the -.B Modes +.B Mode entry description can also be used here. .RE .TP 7 -.BI "Option " "\*qDPMS\*q " \*qbool\*q +.BI "Option \*qDPMS\*q \*q" bool \*q This option controls whether the server should enable the DPMS extension for power management for this screen. The default is to enable the extension. .TP 7 -.BI "Option " "\*qSyncOnGreen\*q " \*qbool\*q +.BI "Option \*qSyncOnGreen\*q \*q" bool \*q This option controls whether the video card should drive the sync signal on the green color pin. Not all cards support this option, and most monitors do not require it. The default is off. .TP 7 -.BI "Option " "\*qPrimary\*q " \*qbool\*q +.BI "Option \*qPrimary\*q \*q" bool \*q This optional entry specifies that the monitor should be treated as the primary monitor. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qPreferredMode\*q " \*qstring\*q +.BI "Option \*qPreferredMode\*q \*q" name \*q This optional entry specifies a mode to be marked as the preferred initial mode of the monitor. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qPosition\*q " "\*qx y\*q" +.BI "Option \*qPosition\*q \*q" x " " y \*q This optional entry specifies the position of the monitor within the X screen. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qLeftOf\*q " \*qoutput\*q +.BI "Option \*qLeftOf\*q \*q" output \*q This optional entry specifies that the monitor should be positioned to the left of the output (not monitor) of the given name. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qRightOf\*q " \*qoutput\*q +.BI "Option \*qRightOf\*q \*q" output \*q This optional entry specifies that the monitor should be positioned to the right of the output (not monitor) of the given name. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qAbove\*q " \*qoutput\*q +.BI "Option \*qAbove\*q \*q" output \*q This optional entry specifies that the monitor should be positioned above the output (not monitor) of the given name. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qBelow\*q " \*qoutput\*q +.BI "Option \*qBelow\*q \*q" output \*q This optional entry specifies that the monitor should be positioned below the output (not monitor) of the given name. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qEnable\*q " \*qbool\*q +.BI "Option \*qEnable\*q \*q" bool \*q This optional entry specifies whether the monitor should be turned on at startup. By default, the server will attempt to enable all connected monitors. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qDefaultModes\*q " \*qbool\*q +.BI "Option \*qDefaultModes\*q \*q" bool \*q This optional entry specifies whether the server should add supported default modes to the list of modes offered on this monitor. By default, the server will add default modes; you should only disable this if you can guarantee @@ -1714,21 +1725,21 @@ that EDID will be available at all times, or if you have added custom modelines which the server can use. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qMinClock\*q " \*qfrequency\*q +.BI "Option \*qMinClock\*q \*q" frequency \*q This optional entry specifies the minimum dot clock, in kHz, that is supported by the monitor. .TP 7 -.BI "Option " "\*qMaxClock\*q " \*qfrequency\*q +.BI "Option \*qMaxClock\*q \*q" frequency \*q This optional entry specifies the maximum dot clock, in kHz, that is supported by the monitor. .TP 7 -.BI "Option " "\*qIgnore\*q " \*qbool\*q +.BI "Option \*qIgnore\*q \*q" bool \*q This optional entry specifies that the monitor should be ignored entirely, and not reported through RandR. This is useful if the hardware reports the presence of outputs that don't exist. (RandR 1.2-supporting drivers only) .TP 7 -.BI "Option " "\*qRotate\*q " \*qrotation\*q +.BI "Option \*qRotate\*q \*q" rotation \*q This optional entry specifies the initial rotation of the given monitor. Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and \*qinverted\*q. diff --git a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c index fb8386022..cc12a31f2 100644 --- a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c +++ b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c @@ -112,7 +112,7 @@ GetBaud (int baudrate) } int -xf86OpenSerial (pointer options) +xf86OpenSerial (XF86OptionPtr options) { struct termios t; int fd, i; @@ -185,7 +185,7 @@ xf86OpenSerial (pointer options) } int -xf86SetSerial (int fd, pointer options) +xf86SetSerial (int fd, XF86OptionPtr options) { struct termios t; int val; diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSproc.h b/xorg-server/hw/xfree86/os-support/xf86_OSproc.h index 3fc332e13..6a29fbdc9 100644 --- a/xorg-server/hw/xfree86/os-support/xf86_OSproc.h +++ b/xorg-server/hw/xfree86/os-support/xf86_OSproc.h @@ -1,220 +1,221 @@ -/*
- * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
- * Copyright 1992 by David Dawes <dawes@XFree86.org>
- * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
- * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
- * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
- * Copyright 1992 by Orest Zborowski <obz@eskimo.com>
- * Copyright 1993 by Vrije Universiteit, The Netherlands
- * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
- * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
- * Copyright 1994-2003 by The XFree86 Project, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of the above listed copyright holders
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. The above listed
- * copyright holders make no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-/*
- * The ARM32 code here carries the following copyright:
- *
- * Copyright 1997
- * Digital Equipment Corporation. All rights reserved.
- * This software is furnished under license and may be used and copied only in
- * accordance with the following terms and conditions. Subject to these
- * conditions, you may download, copy, install, use, modify and distribute
- * this software in source and/or binary form. No title or ownership is
- * transferred hereby.
- *
- * 1) Any source code used, modified or distributed must reproduce and retain
- * this copyright notice and list of conditions as they appear in the
- * source file.
- *
- * 2) No right is granted to use any trade name, trademark, or logo of Digital
- * Equipment Corporation. Neither the "Digital Equipment Corporation"
- * name nor any trademark or logo of Digital Equipment Corporation may be
- * used to endorse or promote products derived from this software without
- * the prior written permission of Digital Equipment Corporation.
- *
- * 3) This software is provided "AS-IS" and any express or implied warranties,
- * including but not limited to, any implied warranties of merchantability,
- * fitness for a particular purpose, or non-infringement are disclaimed.
- * In no event shall DIGITAL be liable for any damages whatsoever, and in
- * particular, DIGITAL shall not be liable for special, indirect,
- * consequential, or incidental damages or damages for lost profits, loss
- * of revenue or loss of use, whether such damages arise in contract,
- * negligence, tort, under statute, in equity, at law or otherwise, even
- * if advised of the possibility of such damage.
- *
- */
-
-
-#ifndef _XF86_OSPROC_H
-#define _XF86_OSPROC_H
-
-/*
- * The actual prototypes have been pulled into this seperate file so
- * that they can can be used without pulling in all of the OS specific
- * stuff like sys/stat.h, etc. This casues problem for loadable modules.
- */
-
-/*
- * Flags for xf86MapVidMem(). Multiple flags can be or'd together. The
- * flags may be used as hints. For example it would be permissible to
- * enable write combining for memory marked only for framebuffer use.
- */
-
-#define VIDMEM_FRAMEBUFFER 0x01 /* memory for framebuffer use */
-#define VIDMEM_MMIO 0x02 /* memory for I/O use */
-#define VIDMEM_MMIO_32BIT 0x04 /* memory accesses >= 32bit */
-#define VIDMEM_READSIDEEFFECT 0x08 /* reads can have side-effects */
-#define VIDMEM_SPARSE 0x10 /* sparse mapping required
- * assumed when VIDMEM_MMIO is
- * set. May be used with
- * VIDMEM_FRAMEBUFFER) */
-#define VIDMEM_READONLY 0x20 /* read-only mapping
- * used when reading BIOS images
- * through xf86MapVidMem() */
-
-/*
- * OS-independent modem state flags for xf86SetSerialModemState() and
- * xf86GetSerialModemState().
- */
-#define XF86_M_LE 0x001 /* line enable */
-#define XF86_M_DTR 0x002 /* data terminal ready */
-#define XF86_M_RTS 0x004 /* request to send */
-#define XF86_M_ST 0x008 /* secondary transmit */
-#define XF86_M_SR 0x010 /* secondary receive */
-#define XF86_M_CTS 0x020 /* clear to send */
-#define XF86_M_CAR 0x040 /* carrier detect */
-#define XF86_M_RNG 0x080 /* ring */
-#define XF86_M_DSR 0x100 /* data set ready */
-
-#ifndef NO_OSLIB_PROTOTYPES
-/*
- * This is to prevent re-entrancy to FatalError() when aborting.
- * Anything that can be called as a result of AbortDDX() should use this
- * instead of FatalError().
- */
-
-#define xf86FatalError(a, b) \
- if (dispatchException & DE_TERMINATE) { \
- ErrorF(a, b); \
- ErrorF("\n"); \
- return; \
- } else FatalError(a, b)
-
-/***************************************************************************/
-/* Prototypes */
-/***************************************************************************/
-
-#include <X11/Xfuncproto.h>
-#include "opaque.h"
-
-_XFUNCPROTOBEGIN
-
-/* public functions */
-extern _X_EXPORT Bool xf86LinearVidMem(void);
-extern _X_EXPORT Bool xf86CheckMTRR(int);
-extern _X_EXPORT pointer xf86MapVidMem(int, int, unsigned long, unsigned long);
-extern _X_EXPORT void xf86UnMapVidMem(int, pointer, unsigned long);
-extern _X_EXPORT void xf86MapReadSideEffects(int, int, pointer, unsigned long);
-extern _X_EXPORT int xf86ReadBIOS(unsigned long, unsigned long, unsigned char *, int);
-extern _X_EXPORT Bool xf86EnableIO(void);
-extern _X_EXPORT void xf86DisableIO(void);
-#ifdef __NetBSD__
-extern _X_EXPORT void xf86SetTVOut(int);
-extern _X_EXPORT void xf86SetRGBOut(void);
-#endif
-extern _X_EXPORT void xf86OSRingBell(int, int, int);
-extern _X_EXPORT void xf86SetReallySlowBcopy(void);
-extern _X_EXPORT void xf86SlowBcopy(unsigned char *, unsigned char *, int);
-extern _X_EXPORT int xf86OpenSerial(pointer options);
-extern _X_EXPORT int xf86SetSerial(int fd, pointer options);
-extern _X_EXPORT int xf86SetSerialSpeed(int fd, int speed);
-extern _X_EXPORT int xf86ReadSerial(int fd, void *buf, int count);
-extern _X_EXPORT int xf86WriteSerial(int fd, const void *buf, int count);
-extern _X_EXPORT int xf86CloseSerial(int fd);
-extern _X_EXPORT int xf86FlushInput(int fd);
-extern _X_EXPORT int xf86WaitForInput(int fd, int timeout);
-extern _X_EXPORT int xf86SerialSendBreak(int fd, int duration);
-extern _X_EXPORT int xf86SetSerialModemState(int fd, int state);
-extern _X_EXPORT int xf86GetSerialModemState(int fd);
-extern _X_EXPORT int xf86SerialModemSetBits(int fd, int bits);
-extern _X_EXPORT int xf86SerialModemClearBits(int fd, int bits);
-extern _X_EXPORT int xf86LoadKernelModule(const char *pathname);
-
-/* AGP GART interface */
-
-typedef struct _AgpInfo {
- CARD32 bridgeId;
- CARD32 agpMode;
- unsigned long base;
- unsigned long size;
- unsigned long totalPages;
- unsigned long systemPages;
- unsigned long usedPages;
-} AgpInfo, *AgpInfoPtr;
-
-extern _X_EXPORT Bool xf86AgpGARTSupported(void);
-extern _X_EXPORT AgpInfoPtr xf86GetAGPInfo(int screenNum);
-extern _X_EXPORT Bool xf86AcquireGART(int screenNum);
-extern _X_EXPORT Bool xf86ReleaseGART(int screenNum);
-extern _X_EXPORT int xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
- unsigned long *physical);
-extern _X_EXPORT Bool xf86DeallocateGARTMemory(int screenNum, int key);
-extern _X_EXPORT Bool xf86BindGARTMemory(int screenNum, int key, unsigned long offset);
-extern _X_EXPORT Bool xf86UnbindGARTMemory(int screenNum, int key);
-extern _X_EXPORT Bool xf86EnableAGP(int screenNum, CARD32 mode);
-extern _X_EXPORT Bool xf86GARTCloseScreen(int screenNum);
-
-/* These routines are in shared/sigio.c and are not loaded as part of the
- module. These routines are small, and the code if very POSIX-signal (or
- OS-signal) specific, so it seemed better to provide more complex
- wrappers than to wrap each individual function called. */
-extern _X_EXPORT int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
-extern _X_EXPORT int xf86RemoveSIGIOHandler(int fd);
-extern _X_EXPORT int xf86BlockSIGIO (void);
-extern _X_EXPORT void xf86UnblockSIGIO (int);
-extern _X_EXPORT void xf86AssertBlockedSIGIO (char *);
-extern _X_EXPORT Bool xf86SIGIOSupported (void);
-
-#ifdef XF86_OS_PRIVS
-typedef void (*PMClose)(void);
-extern _X_EXPORT void xf86OpenConsole(void);
-extern _X_EXPORT void xf86CloseConsole(void);
-extern _X_HIDDEN Bool xf86VTActivate(int vtno);
-extern _X_EXPORT Bool xf86VTSwitchPending(void);
-extern _X_EXPORT Bool xf86VTSwitchAway(void);
-extern _X_EXPORT Bool xf86VTSwitchTo(void);
-extern _X_EXPORT void xf86VTRequest(int sig);
-extern _X_EXPORT int xf86ProcessArgument(int, char **, int);
-extern _X_EXPORT void xf86UseMsg(void);
-extern _X_EXPORT PMClose xf86OSPMOpen(void);
-
-extern _X_EXPORT void xf86MakeNewMapping(int, int, unsigned long, unsigned long, pointer);
-extern _X_EXPORT void xf86InitVidMem(void);
-
-#endif /* XF86_OS_PRIVS */
-
-
-_XFUNCPROTOEND
-#endif /* NO_OSLIB_PROTOTYPES */
-
-#endif /* _XF86_OSPROC_H */
+/* + * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1992 by David Dawes <dawes@XFree86.org> + * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu> + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu> + * Copyright 1992 by Orest Zborowski <obz@eskimo.com> + * Copyright 1993 by Vrije Universiteit, The Netherlands + * Copyright 1993 by David Wexelblat <dwex@XFree86.org> + * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de> + * Copyright 1994-2003 by The XFree86 Project, Inc + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of the above listed copyright holders + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holders make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* + * The ARM32 code here carries the following copyright: + * + * Copyright 1997 + * Digital Equipment Corporation. All rights reserved. + * This software is furnished under license and may be used and copied only in + * accordance with the following terms and conditions. Subject to these + * conditions, you may download, copy, install, use, modify and distribute + * this software in source and/or binary form. No title or ownership is + * transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce and retain + * this copyright notice and list of conditions as they appear in the + * source file. + * + * 2) No right is granted to use any trade name, trademark, or logo of Digital + * Equipment Corporation. Neither the "Digital Equipment Corporation" + * name nor any trademark or logo of Digital Equipment Corporation may be + * used to endorse or promote products derived from this software without + * the prior written permission of Digital Equipment Corporation. + * + * 3) This software is provided "AS-IS" and any express or implied warranties, + * including but not limited to, any implied warranties of merchantability, + * fitness for a particular purpose, or non-infringement are disclaimed. + * In no event shall DIGITAL be liable for any damages whatsoever, and in + * particular, DIGITAL shall not be liable for special, indirect, + * consequential, or incidental damages or damages for lost profits, loss + * of revenue or loss of use, whether such damages arise in contract, + * negligence, tort, under statute, in equity, at law or otherwise, even + * if advised of the possibility of such damage. + * + */ + + +#ifndef _XF86_OSPROC_H +#define _XF86_OSPROC_H + +/* + * The actual prototypes have been pulled into this seperate file so + * that they can can be used without pulling in all of the OS specific + * stuff like sys/stat.h, etc. This casues problem for loadable modules. + */ + +/* + * Flags for xf86MapVidMem(). Multiple flags can be or'd together. The + * flags may be used as hints. For example it would be permissible to + * enable write combining for memory marked only for framebuffer use. + */ + +#define VIDMEM_FRAMEBUFFER 0x01 /* memory for framebuffer use */ +#define VIDMEM_MMIO 0x02 /* memory for I/O use */ +#define VIDMEM_MMIO_32BIT 0x04 /* memory accesses >= 32bit */ +#define VIDMEM_READSIDEEFFECT 0x08 /* reads can have side-effects */ +#define VIDMEM_SPARSE 0x10 /* sparse mapping required + * assumed when VIDMEM_MMIO is + * set. May be used with + * VIDMEM_FRAMEBUFFER) */ +#define VIDMEM_READONLY 0x20 /* read-only mapping + * used when reading BIOS images + * through xf86MapVidMem() */ + +/* + * OS-independent modem state flags for xf86SetSerialModemState() and + * xf86GetSerialModemState(). + */ +#define XF86_M_LE 0x001 /* line enable */ +#define XF86_M_DTR 0x002 /* data terminal ready */ +#define XF86_M_RTS 0x004 /* request to send */ +#define XF86_M_ST 0x008 /* secondary transmit */ +#define XF86_M_SR 0x010 /* secondary receive */ +#define XF86_M_CTS 0x020 /* clear to send */ +#define XF86_M_CAR 0x040 /* carrier detect */ +#define XF86_M_RNG 0x080 /* ring */ +#define XF86_M_DSR 0x100 /* data set ready */ + +#ifndef NO_OSLIB_PROTOTYPES +/* + * This is to prevent re-entrancy to FatalError() when aborting. + * Anything that can be called as a result of AbortDDX() should use this + * instead of FatalError(). + */ + +#define xf86FatalError(a, b) \ + if (dispatchException & DE_TERMINATE) { \ + ErrorF(a, b); \ + ErrorF("\n"); \ + return; \ + } else FatalError(a, b) + +/***************************************************************************/ +/* Prototypes */ +/***************************************************************************/ + +#include <X11/Xfuncproto.h> +#include "opaque.h" +#include "xf86Optionstr.h" + +_XFUNCPROTOBEGIN + +/* public functions */ +extern _X_EXPORT Bool xf86LinearVidMem(void); +extern _X_EXPORT Bool xf86CheckMTRR(int); +extern _X_EXPORT pointer xf86MapVidMem(int, int, unsigned long, unsigned long); +extern _X_EXPORT void xf86UnMapVidMem(int, pointer, unsigned long); +extern _X_EXPORT void xf86MapReadSideEffects(int, int, pointer, unsigned long); +extern _X_EXPORT int xf86ReadBIOS(unsigned long, unsigned long, unsigned char *, int); +extern _X_EXPORT Bool xf86EnableIO(void); +extern _X_EXPORT void xf86DisableIO(void); +#ifdef __NetBSD__ +extern _X_EXPORT void xf86SetTVOut(int); +extern _X_EXPORT void xf86SetRGBOut(void); +#endif +extern _X_EXPORT void xf86OSRingBell(int, int, int); +extern _X_EXPORT void xf86SetReallySlowBcopy(void); +extern _X_EXPORT void xf86SlowBcopy(unsigned char *, unsigned char *, int); +extern _X_EXPORT int xf86OpenSerial(XF86OptionPtr options); +extern _X_EXPORT int xf86SetSerial(int fd, XF86OptionPtr options); +extern _X_EXPORT int xf86SetSerialSpeed(int fd, int speed); +extern _X_EXPORT int xf86ReadSerial(int fd, void *buf, int count); +extern _X_EXPORT int xf86WriteSerial(int fd, const void *buf, int count); +extern _X_EXPORT int xf86CloseSerial(int fd); +extern _X_EXPORT int xf86FlushInput(int fd); +extern _X_EXPORT int xf86WaitForInput(int fd, int timeout); +extern _X_EXPORT int xf86SerialSendBreak(int fd, int duration); +extern _X_EXPORT int xf86SetSerialModemState(int fd, int state); +extern _X_EXPORT int xf86GetSerialModemState(int fd); +extern _X_EXPORT int xf86SerialModemSetBits(int fd, int bits); +extern _X_EXPORT int xf86SerialModemClearBits(int fd, int bits); +extern _X_EXPORT int xf86LoadKernelModule(const char *pathname); + +/* AGP GART interface */ + +typedef struct _AgpInfo { + CARD32 bridgeId; + CARD32 agpMode; + unsigned long base; + unsigned long size; + unsigned long totalPages; + unsigned long systemPages; + unsigned long usedPages; +} AgpInfo, *AgpInfoPtr; + +extern _X_EXPORT Bool xf86AgpGARTSupported(void); +extern _X_EXPORT AgpInfoPtr xf86GetAGPInfo(int screenNum); +extern _X_EXPORT Bool xf86AcquireGART(int screenNum); +extern _X_EXPORT Bool xf86ReleaseGART(int screenNum); +extern _X_EXPORT int xf86AllocateGARTMemory(int screenNum, unsigned long size, int type, + unsigned long *physical); +extern _X_EXPORT Bool xf86DeallocateGARTMemory(int screenNum, int key); +extern _X_EXPORT Bool xf86BindGARTMemory(int screenNum, int key, unsigned long offset); +extern _X_EXPORT Bool xf86UnbindGARTMemory(int screenNum, int key); +extern _X_EXPORT Bool xf86EnableAGP(int screenNum, CARD32 mode); +extern _X_EXPORT Bool xf86GARTCloseScreen(int screenNum); + +/* These routines are in shared/sigio.c and are not loaded as part of the + module. These routines are small, and the code if very POSIX-signal (or + OS-signal) specific, so it seemed better to provide more complex + wrappers than to wrap each individual function called. */ +extern _X_EXPORT int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); +extern _X_EXPORT int xf86RemoveSIGIOHandler(int fd); +extern _X_EXPORT int xf86BlockSIGIO (void); +extern _X_EXPORT void xf86UnblockSIGIO (int); +extern _X_EXPORT void xf86AssertBlockedSIGIO (char *); +extern _X_EXPORT Bool xf86SIGIOSupported (void); + +#ifdef XF86_OS_PRIVS +typedef void (*PMClose)(void); +extern _X_EXPORT void xf86OpenConsole(void); +extern _X_EXPORT void xf86CloseConsole(void); +extern _X_HIDDEN Bool xf86VTActivate(int vtno); +extern _X_EXPORT Bool xf86VTSwitchPending(void); +extern _X_EXPORT Bool xf86VTSwitchAway(void); +extern _X_EXPORT Bool xf86VTSwitchTo(void); +extern _X_EXPORT void xf86VTRequest(int sig); +extern _X_EXPORT int xf86ProcessArgument(int, char **, int); +extern _X_EXPORT void xf86UseMsg(void); +extern _X_EXPORT PMClose xf86OSPMOpen(void); + +extern _X_EXPORT void xf86MakeNewMapping(int, int, unsigned long, unsigned long, pointer); +extern _X_EXPORT void xf86InitVidMem(void); + +#endif /* XF86_OS_PRIVS */ + + +_XFUNCPROTOEND +#endif /* NO_OSLIB_PROTOTYPES */ + +#endif /* _XF86_OSPROC_H */ diff --git a/xorg-server/hw/xfree86/parser/Makefile.am b/xorg-server/hw/xfree86/parser/Makefile.am index 1cd70e7a5..002cfbf5c 100644 --- a/xorg-server/hw/xfree86/parser/Makefile.am +++ b/xorg-server/hw/xfree86/parser/Makefile.am @@ -50,3 +50,5 @@ EXTRA_DIST = \ sdk_HEADERS = \ xf86Parser.h \ xf86Optrec.h + +INCLUDES = -I$(srcdir)/../common diff --git a/xorg-server/hw/xfree86/parser/xf86Optrec.h b/xorg-server/hw/xfree86/parser/xf86Optrec.h index 5ccf7285b..61a8c5ff5 100644 --- a/xorg-server/hw/xfree86/parser/xf86Optrec.h +++ b/xorg-server/hw/xfree86/parser/xf86Optrec.h @@ -65,33 +65,10 @@ #define _xf86Optrec_h_ #include <stdio.h> #include <string.h> +#include "xf86Optionstr.h" #include <X11/Xfuncproto.h> -/* - * all records that need to be linked lists should contain a GenericList as - * their first field. - */ -typedef struct generic_list_rec -{ - void *next; -} -GenericListRec, *GenericListPtr, *glp; - -/* - * All options are stored using this data type. - */ -typedef struct -{ - GenericListRec list; - char *opt_name; - char *opt_val; - int opt_used; - char *opt_comment; -} -XF86OptionRec, *XF86OptionPtr; - - extern _X_EXPORT XF86OptionPtr xf86addNewOption(XF86OptionPtr head, char *name, char *val); extern _X_EXPORT XF86OptionPtr xf86optionListDup(XF86OptionPtr opt); extern _X_EXPORT void xf86optionListFree(XF86OptionPtr opt); diff --git a/xorg-server/include/globals.h b/xorg-server/include/globals.h index e9a6028dd..17bca8208 100644 --- a/xorg-server/include/globals.h +++ b/xorg-server/include/globals.h @@ -1,125 +1,125 @@ -
-#ifndef _XSERV_GLOBAL_H_
-#define _XSERV_GLOBAL_H_
-
-#include "window.h" /* for WindowPtr */
-
-/* Global X server variables that are visible to mi, dix, os, and ddx */
-
-extern _X_EXPORT CARD32 defaultScreenSaverTime;
-extern _X_EXPORT CARD32 defaultScreenSaverInterval;
-extern _X_EXPORT CARD32 ScreenSaverTime;
-extern _X_EXPORT CARD32 ScreenSaverInterval;
-
-#ifdef SCREENSAVER
-extern _X_EXPORT Bool screenSaverSuspended;
-#endif
-
-extern _X_EXPORT char *defaultFontPath;
-extern _X_EXPORT int monitorResolution;
-extern _X_EXPORT int defaultColorVisualClass;
-
-extern _X_EXPORT int GrabInProgress;
-extern _X_EXPORT Bool noTestExtensions;
-
-extern _X_EXPORT char *ConnectionInfo;
-
-#ifdef DPMSExtension
-extern _X_EXPORT CARD32 DPMSStandbyTime;
-extern _X_EXPORT CARD32 DPMSSuspendTime;
-extern _X_EXPORT CARD32 DPMSOffTime;
-extern _X_EXPORT CARD16 DPMSPowerLevel;
-extern _X_EXPORT Bool DPMSEnabled;
-extern _X_EXPORT Bool DPMSDisabledSwitch;
-extern _X_EXPORT Bool DPMSCapableFlag;
-#endif
-
-#ifdef PANORAMIX
-extern _X_EXPORT Bool PanoramiXExtensionDisabledHack;
-#endif
-
-#ifdef COMPOSITE
-extern _X_EXPORT Bool noCompositeExtension;
-#endif
-
-#ifdef DAMAGE
-extern _X_EXPORT Bool noDamageExtension;
-#endif
-
-#ifdef DBE
-extern _X_EXPORT Bool noDbeExtension;
-#endif
-
-#ifdef DPMSExtension
-extern _X_EXPORT Bool noDPMSExtension;
-#endif
-
-#ifdef GLXEXT
-extern _X_EXPORT Bool noGlxExtension;
-#endif
-
-#ifdef SCREENSAVER
-extern _X_EXPORT Bool noScreenSaverExtension;
-#endif
-
-#ifdef MITSHM
-extern _X_EXPORT Bool noMITShmExtension;
-#endif
-
-#ifdef RANDR
-extern _X_EXPORT Bool noRRExtension;
-#endif
-
-extern _X_EXPORT Bool noRenderExtension;
-
-#ifdef XCSECURITY
-extern _X_EXPORT Bool noSecurityExtension;
-#endif
-
-#ifdef RES
-extern _X_EXPORT Bool noResExtension;
-#endif
-
-#ifdef XF86BIGFONT
-extern _X_EXPORT Bool noXFree86BigfontExtension;
-#endif
-
-#ifdef XFreeXDGA
-extern _X_EXPORT Bool noXFree86DGAExtension;
-#endif
-
-#ifdef XF86DRI
-extern _X_EXPORT Bool noXFree86DRIExtension;
-#endif
-
-#ifdef XF86VIDMODE
-extern _X_EXPORT Bool noXFree86VidModeExtension;
-#endif
-
-#ifdef XFIXES
-extern _X_EXPORT Bool noXFixesExtension;
-#endif
-
-#ifdef PANORAMIX
-extern _X_EXPORT Bool noPanoramiXExtension;
-#endif
-
-#ifdef XSELINUX
-extern _X_EXPORT Bool noSELinuxExtension;
-
-#define SELINUX_MODE_DEFAULT 0
-#define SELINUX_MODE_DISABLED 1
-#define SELINUX_MODE_PERMISSIVE 2
-#define SELINUX_MODE_ENFORCING 3
-extern _X_EXPORT int selinuxEnforcingState;
-#endif
-
-#ifdef XV
-extern _X_EXPORT Bool noXvExtension;
-#endif
-
-#ifdef DRI2
-extern _X_EXPORT Bool noDRI2Extension;
-#endif
-
-#endif /* !_XSERV_GLOBAL_H_ */
+ +#ifndef _XSERV_GLOBAL_H_ +#define _XSERV_GLOBAL_H_ + +#include "window.h" /* for WindowPtr */ + +/* Global X server variables that are visible to mi, dix, os, and ddx */ + +extern _X_EXPORT CARD32 defaultScreenSaverTime; +extern _X_EXPORT CARD32 defaultScreenSaverInterval; +extern _X_EXPORT CARD32 ScreenSaverTime; +extern _X_EXPORT CARD32 ScreenSaverInterval; + +#ifdef SCREENSAVER +extern _X_EXPORT Bool screenSaverSuspended; +#endif + +extern _X_EXPORT char *defaultFontPath; +extern _X_EXPORT int monitorResolution; +extern _X_EXPORT int defaultColorVisualClass; + +extern _X_EXPORT int GrabInProgress; +extern _X_EXPORT Bool noTestExtensions; +extern _X_EXPORT char *SeatId; +extern _X_EXPORT char *ConnectionInfo; + +#ifdef DPMSExtension +extern _X_EXPORT CARD32 DPMSStandbyTime; +extern _X_EXPORT CARD32 DPMSSuspendTime; +extern _X_EXPORT CARD32 DPMSOffTime; +extern _X_EXPORT CARD16 DPMSPowerLevel; +extern _X_EXPORT Bool DPMSEnabled; +extern _X_EXPORT Bool DPMSDisabledSwitch; +extern _X_EXPORT Bool DPMSCapableFlag; +#endif + +#ifdef PANORAMIX +extern _X_EXPORT Bool PanoramiXExtensionDisabledHack; +#endif + +#ifdef COMPOSITE +extern _X_EXPORT Bool noCompositeExtension; +#endif + +#ifdef DAMAGE +extern _X_EXPORT Bool noDamageExtension; +#endif + +#ifdef DBE +extern _X_EXPORT Bool noDbeExtension; +#endif + +#ifdef DPMSExtension +extern _X_EXPORT Bool noDPMSExtension; +#endif + +#ifdef GLXEXT +extern _X_EXPORT Bool noGlxExtension; +#endif + +#ifdef SCREENSAVER +extern _X_EXPORT Bool noScreenSaverExtension; +#endif + +#ifdef MITSHM +extern _X_EXPORT Bool noMITShmExtension; +#endif + +#ifdef RANDR +extern _X_EXPORT Bool noRRExtension; +#endif + +extern _X_EXPORT Bool noRenderExtension; + +#ifdef XCSECURITY +extern _X_EXPORT Bool noSecurityExtension; +#endif + +#ifdef RES +extern _X_EXPORT Bool noResExtension; +#endif + +#ifdef XF86BIGFONT +extern _X_EXPORT Bool noXFree86BigfontExtension; +#endif + +#ifdef XFreeXDGA +extern _X_EXPORT Bool noXFree86DGAExtension; +#endif + +#ifdef XF86DRI +extern _X_EXPORT Bool noXFree86DRIExtension; +#endif + +#ifdef XF86VIDMODE +extern _X_EXPORT Bool noXFree86VidModeExtension; +#endif + +#ifdef XFIXES +extern _X_EXPORT Bool noXFixesExtension; +#endif + +#ifdef PANORAMIX +extern _X_EXPORT Bool noPanoramiXExtension; +#endif + +#ifdef XSELINUX +extern _X_EXPORT Bool noSELinuxExtension; + +#define SELINUX_MODE_DEFAULT 0 +#define SELINUX_MODE_DISABLED 1 +#define SELINUX_MODE_PERMISSIVE 2 +#define SELINUX_MODE_ENFORCING 3 +extern _X_EXPORT int selinuxEnforcingState; +#endif + +#ifdef XV +extern _X_EXPORT Bool noXvExtension; +#endif + +#ifdef DRI2 +extern _X_EXPORT Bool noDRI2Extension; +#endif + +#endif /* !_XSERV_GLOBAL_H_ */ diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index 5377a0c13..0258f4f18 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -56,6 +56,7 @@ SOFTWARE. #include "window.h" /* for WindowPtr */ #include "xkbrules.h" #include "events.h" +#include "list.h" #define DEVICE_INIT 0 #define DEVICE_ON 1 @@ -202,11 +203,7 @@ typedef struct { extern _X_EXPORT KeybdCtrl defaultKeyboardControl; extern _X_EXPORT PtrCtrl defaultPointerControl; -typedef struct _InputOption { - char *key; - char *value; - struct _InputOption *next; -} InputOption; +typedef struct _InputOption InputOption; typedef struct _InputAttributes { char *product; @@ -595,4 +592,14 @@ extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src); extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum); +/* InputOption handling interface */ +extern _X_EXPORT InputOption* input_option_new(InputOption *list, const char *key, const char *value); +extern _X_EXPORT void input_option_free_list(InputOption **opt); +extern _X_EXPORT InputOption* input_option_free_element(InputOption *opt, const char *key); +extern _X_EXPORT InputOption* input_option_find(InputOption *list, const char *key); +extern _X_EXPORT const char* input_option_get_key(const InputOption *opt); +extern _X_EXPORT const char* input_option_get_value(const InputOption *opt); +extern _X_EXPORT void input_option_set_key(InputOption *opt, const char* key); +extern _X_EXPORT void input_option_set_value(InputOption *opt, const char* value); + #endif /* INPUT_H */ diff --git a/xorg-server/include/inputstr.h b/xorg-server/include/inputstr.h index 00f72c260..480e95671 100644 --- a/xorg-server/include/inputstr.h +++ b/xorg-server/include/inputstr.h @@ -472,7 +472,10 @@ typedef struct _SpriteInfoRec { #define MASTER_POINTER 1 #define MASTER_KEYBOARD 2 #define SLAVE 3 -#define MASTER_ATTACHED 4 /* special type for GetMaster */ +/* special types for GetMaster */ +#define MASTER_ATTACHED 4 /* Master for this device */ +#define KEYBOARD_OR_FLOAT 5 /* Keyboard master for this device or this device if floating */ +#define POINTER_OR_FLOAT 6 /* Pointer master for this device or this device if floating */ typedef struct _DeviceIntRec { DeviceRec public; @@ -599,4 +602,11 @@ static inline WindowPtr DeepestSpriteWin(SpritePtr sprite) return sprite->spriteTrace[sprite->spriteTraceGood - 1]; } +struct _InputOption { + char *key; + char *value; + struct _InputOption *next; +}; + + #endif /* INPUTSTRUCT_H */ diff --git a/xorg-server/include/inpututils.h b/xorg-server/include/inpututils.h index 92a754327..63e1a263a 100644 --- a/xorg-server/include/inpututils.h +++ b/xorg-server/include/inpututils.h @@ -38,5 +38,6 @@ struct _ValuatorMask { }; extern void verify_internal_event(const InternalEvent *ev); +extern void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms); #endif diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h index 5933b973d..7825dce52 100644 --- a/xorg-server/include/list.h +++ b/xorg-server/include/list.h @@ -278,4 +278,164 @@ list_is_empty(struct list *head) &pos->member != (head); \ pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) + + +/* NULL-Terminated List Interface + * + * The interface below does _not_ use the struct list as described above. + * It is mainly for legacy structures that cannot easily be switched to + * struct list. + * + * This interface is for structs like + * struct foo { + * [...] + * struct foo *next; + * [...] + * }; + * + * The position and field name of "next" are arbitrary. + */ + +/** + * Init the element as null-terminated list. + * + * Example: + * struct foo *list = malloc(); + * nt_list_init(list, next); + * + * @param list The list element that will be the start of the list + * @param member Member name of the field pointing to next struct + */ +#define nt_list_init(_list, _member) \ + (_list)->_member = NULL + +/** + * Returns the next element in the list or NULL on termination. + * + * Example: + * struct foo *element = list; + * while ((element = nt_list_next(element, next)) { } + * + * This macro is not safe for node deletion. Use list_for_each_entry_safe + * instead. + * + * @param list The list or current element. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_next(_list, _member) \ + (_list)->_member + +/** + * Iterate through each element in the list. + * + * Example: + * struct foo *iterator; + * nt_list_for_each_entry(iterator, list, next) { + * [modify iterator] + * } + * + * @param entry Assigned to the current list element + * @param list The list to iterate through. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_for_each_entry(_entry, _list, _member) \ + for (_entry = _list; _entry; _entry = (_entry)->_member) + +/** + * Iterate through each element in the list, keeping a backup pointer to the + * element. This macro allows for the deletion of a list element while + * looping through the list. + * + * See nt_list_for_each_entry for more details. + * + * @param entry Assigned to the current list element + * @param tmp The pointer to the next element + * @param list The list to iterate through. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_for_each_entry_safe(_entry, _tmp, _list, _member) \ + for (_entry = _list, _tmp = (_entry) ? (_entry)->_member : NULL;\ + _entry; \ + _entry = _tmp, _tmp = (_tmp) ? (_tmp)->_member: NULL) + + +/** + * Append the element to the end of the list. This macro may be used to + * merge two lists. + * + * Example: + * struct foo *elem = malloc(...); + * nt_list_init(elem, next) + * nt_list_append(elem, list, struct foo, next); + * + * Resulting list order: + * list_item_0 -> list_item_1 -> ... -> elem_item_0 -> elem_item_1 ... + * + * @param entry An entry (or list) to append to the list + * @param list The list to append to. This list must be a valid list, not + * NULL. + * @param type The list type + * @param member Member name of the field pointing to next struct + */ +#define nt_list_append(_entry, _list, _type, _member) \ + do { \ + _type *__iterator = _list; \ + while (__iterator->_member) { __iterator = __iterator->_member;}\ + __iterator->_member = _entry; \ + } while (0) + +/** + * Insert the element at the next position in the list. This macro may be + * used to insert a list into a list. + * + * struct foo *elem = malloc(...); + * nt_list_init(elem, next) + * nt_list_insert(elem, list, struct foo, next); + * + * Resulting list order: + * list_item_0 -> elem_item_0 -> elem_item_1 ... -> list_item_1 -> ... + * + * @param entry An entry (or list) to append to the list + * @param list The list to insert to. This list must be a valid list, not + * NULL. + * @param type The list type + * @param member Member name of the field pointing to next struct + */ +#define nt_list_insert(_entry, _list, _type, _member) \ + do { \ + nt_list_append((_list)->_member, _entry, _type, _member); \ + (_list)->_member = _entry; \ + } while (0) + +/** + * Delete the entry from the list by iterating through the list and + * removing any reference from the list to the entry. + * + * Example: + * struct foo *elem = <assign to right element> + * nt_list_del(elem, list, struct foo, next); + * + * @param entry The entry to delete from the list. entry is always + * re-initialized as a null-terminated list. + * @param list The list containing the entry, set to the new list without + * the removed entry. + * @param type The list type + * @param member Member name of the field pointing to the next entry + */ +#define nt_list_del(_entry, _list, _type, _member) \ + do { \ + _type *__e = _entry; \ + if (__e == NULL) break; \ + if ((_list) == __e) { \ + _list = __e->_member; \ + } else { \ + _type *__prev = _list; \ + while (__prev->_member && __prev->_member != __e) \ + __prev = nt_list_next(__prev, _member); \ + if (__prev->_member) \ + __prev->_member = __e->_member; \ + } \ + nt_list_init(__e, _member); \ + } while(0) + #endif diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index a553f5783..5401ea478 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -525,6 +525,19 @@ extern _X_EXPORT void LogMessageVerb(MessageType type, int verb, const char *for ...) _X_ATTRIBUTE_PRINTF(3,4); extern _X_EXPORT void LogMessage(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3); + +extern _X_EXPORT void LogVHdrMessageVerb(MessageType type, int verb, + const char *msg_format, va_list msg_args, + const char *hdr_format, va_list hdr_args) + _X_ATTRIBUTE_PRINTF(3,0) _X_ATTRIBUTE_PRINTF(5,0); +extern _X_EXPORT void LogHdrMessageVerb(MessageType type, int verb, + const char *msg_format, va_list msg_args, + const char *hdr_format, ...) + _X_ATTRIBUTE_PRINTF(3,0) _X_ATTRIBUTE_PRINTF(5,6); +extern _X_EXPORT void LogHdrMessage(MessageType type, const char *msg_format, + va_list msg_args, const char *hdr_format, ...) + _X_ATTRIBUTE_PRINTF(2,0) _X_ATTRIBUTE_PRINTF(4,5); + extern _X_EXPORT void FreeAuditTimer(void); extern _X_EXPORT void AuditF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); extern _X_EXPORT void VAuditF(const char *f, va_list args) _X_ATTRIBUTE_PRINTF(1,0); diff --git a/xorg-server/include/xserver-properties.h b/xorg-server/include/xserver-properties.h index 2b1feabb6..bf50042d0 100644 --- a/xorg-server/include/xserver-properties.h +++ b/xorg-server/include/xserver-properties.h @@ -30,6 +30,9 @@ * byte-ordering. */ #define XATOM_FLOAT "FLOAT" +/* STRING. Seat name of this display */ +#define SEAT_ATOM_NAME "Xorg_Seat" + /* BOOL. 0 - device disabled, 1 - device enabled */ #define XI_PROP_ENABLED "Device Enabled" /* BOOL. If present, device is a virtual XTEST device */ diff --git a/xorg-server/man/Xserver.man b/xorg-server/man/Xserver.man index f74391212..1a36b0956 100644 --- a/xorg-server/man/Xserver.man +++ b/xorg-server/man/Xserver.man @@ -220,6 +220,12 @@ sets screen-saver timeout time in minutes. .B \-su disables save under support on all screens. .TP 8 +.B \-seat \fIseat\fP +seat to run on. Takes a string identifying a seat in a platform +specific syntax. On platforms which support this feature this may be +used to limit the server to expose only a specific subset of devices +connected to the system. +.TP 8 .B \-t \fInumber\fP sets pointer acceleration threshold in pixels (i.e. after how many pixels pointer acceleration should take effect). diff --git a/xorg-server/mi/mi.h b/xorg-server/mi/mi.h index ea5424823..24d1af911 100644 --- a/xorg-server/mi/mi.h +++ b/xorg-server/mi/mi.h @@ -1,599 +1,599 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef MI_H
-#define MI_H
-#include <X11/X.h>
-#include "region.h"
-#include "validate.h"
-#include "window.h"
-#include "gc.h"
-#include <X11/fonts/font.h>
-#include "input.h"
-#include "cursor.h"
-#include "privates.h"
-#include "colormap.h"
-#include "events.h"
-
-#define MiBits CARD32
-
-typedef struct _miDash *miDashPtr;
-#define EVEN_DASH 0
-#define ODD_DASH ~0
-
-/* miarc.c */
-
-extern _X_EXPORT void miPolyArc(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*narcs*/,
- xArc * /*parcs*/
-);
-
-/* mibitblt.c */
-
-extern _X_EXPORT RegionPtr miCopyArea(
- DrawablePtr /*pSrcDrawable*/,
- DrawablePtr /*pDstDrawable*/,
- GCPtr /*pGC*/,
- int /*xIn*/,
- int /*yIn*/,
- int /*widthSrc*/,
- int /*heightSrc*/,
- int /*xOut*/,
- int /*yOut*/
-);
-
-extern _X_EXPORT RegionPtr miCopyPlane(
- DrawablePtr /*pSrcDrawable*/,
- DrawablePtr /*pDstDrawable*/,
- GCPtr /*pGC*/,
- int /*srcx*/,
- int /*srcy*/,
- int /*width*/,
- int /*height*/,
- int /*dstx*/,
- int /*dsty*/,
- unsigned long /*bitPlane*/
-);
-
-extern _X_EXPORT void miGetImage(
- DrawablePtr /*pDraw*/,
- int /*sx*/,
- int /*sy*/,
- int /*w*/,
- int /*h*/,
- unsigned int /*format*/,
- unsigned long /*planeMask*/,
- char * /*pdstLine*/
-);
-
-extern _X_EXPORT void miPutImage(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*depth*/,
- int /*x*/,
- int /*y*/,
- int /*w*/,
- int /*h*/,
- int /*leftPad*/,
- int /*format*/,
- char * /*pImage*/
-);
-
-/* micopy.c */
-
-#define miGetCompositeClip(pGC) ((pGC)->pCompositeClip)
-
-typedef void (*miCopyProc) (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pDstBox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown,
- Pixel bitplane,
- void *closure);
-
-extern _X_EXPORT void
-miCopyRegion (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- RegionPtr pDstRegion,
- int dx,
- int dy,
- miCopyProc copyProc,
- Pixel bitPlane,
- void *closure);
-
-extern _X_EXPORT RegionPtr
-miDoCopy (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- int xIn,
- int yIn,
- int widthSrc,
- int heightSrc,
- int xOut,
- int yOut,
- miCopyProc copyProc,
- Pixel bitplane,
- void *closure);
-
-/* micursor.c */
-
-extern _X_EXPORT void miRecolorCursor(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScr*/,
- CursorPtr /*pCurs*/,
- Bool /*displayed*/
-);
-
-/* midash.c */
-
-extern _X_EXPORT void miStepDash(
- int /*dist*/,
- int * /*pDashIndex*/,
- unsigned char * /*pDash*/,
- int /*numInDashList*/,
- int * /*pDashOffset*/
-);
-
-/* mieq.c */
-
-
-#ifndef INPUT_H
-typedef struct _DeviceRec *DevicePtr;
-#endif
-
-extern _X_EXPORT Bool mieqInit(
- void
-);
-
-extern _X_EXPORT void mieqFini(void);
-
-extern _X_EXPORT void mieqEnqueue(
- DeviceIntPtr /*pDev*/,
- InternalEvent* /*e*/
-);
-
-extern _X_EXPORT void mieqSwitchScreen(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- Bool /*fromDIX*/
-);
-
-extern _X_EXPORT void mieqProcessDeviceEvent(
- DeviceIntPtr /* dev*/,
- InternalEvent* /* event */,
- ScreenPtr /* screen*/
-);
-
-extern _X_EXPORT void mieqProcessInputEvents(
- void
-);
-
-extern DeviceIntPtr CopyGetMasterEvent(
- DeviceIntPtr /* sdev */,
- InternalEvent* /* original */,
- InternalEvent* /* copy */
-);
-
-/**
- * Custom input event handler. If you need to process input events in some
- * other way than the default path, register an input event handler for the
- * given internal event type.
- */
-typedef void (*mieqHandler)(int screen, InternalEvent* event, DeviceIntPtr dev);
-void _X_EXPORT mieqSetHandler(int event, mieqHandler handler);
-
-/* miexpose.c */
-
-extern _X_EXPORT RegionPtr miHandleExposures(
- DrawablePtr /*pSrcDrawable*/,
- DrawablePtr /*pDstDrawable*/,
- GCPtr /*pGC*/,
- int /*srcx*/,
- int /*srcy*/,
- int /*width*/,
- int /*height*/,
- int /*dstx*/,
- int /*dsty*/,
- unsigned long /*plane*/
-);
-
-extern _X_EXPORT void miSendGraphicsExpose(
- ClientPtr /*client*/,
- RegionPtr /*pRgn*/,
- XID /*drawable*/,
- int /*major*/,
- int /*minor*/
-);
-
-extern _X_EXPORT void miSendExposures(
- WindowPtr /*pWin*/,
- RegionPtr /*pRgn*/,
- int /*dx*/,
- int /*dy*/
-);
-
-extern _X_EXPORT void miWindowExposures(
- WindowPtr /*pWin*/,
- RegionPtr /*prgn*/,
- RegionPtr /*other_exposed*/
-);
-
-extern _X_EXPORT void miPaintWindow(
- WindowPtr /*pWin*/,
- RegionPtr /*prgn*/,
- int /*what*/
-);
-
-extern _X_EXPORT void miClearDrawable(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/
-);
-
-/* mifillrct.c */
-
-extern _X_EXPORT void miPolyFillRect(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*nrectFill*/,
- xRectangle * /*prectInit*/
-);
-
-/* miglblt.c */
-
-extern _X_EXPORT void miPolyGlyphBlt(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- unsigned int /*nglyph*/,
- CharInfoPtr * /*ppci*/,
- pointer /*pglyphBase*/
-);
-
-extern _X_EXPORT void miImageGlyphBlt(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- unsigned int /*nglyph*/,
- CharInfoPtr * /*ppci*/,
- pointer /*pglyphBase*/
-);
-
-/* mipoly.c */
-
-extern _X_EXPORT void miFillPolygon(
- DrawablePtr /*dst*/,
- GCPtr /*pgc*/,
- int /*shape*/,
- int /*mode*/,
- int /*count*/,
- DDXPointPtr /*pPts*/
-);
-
-/* mipolycon.c */
-
-extern _X_EXPORT Bool miFillConvexPoly(
- DrawablePtr /*dst*/,
- GCPtr /*pgc*/,
- int /*count*/,
- DDXPointPtr /*ptsIn*/
-);
-
-/* mipolygen.c */
-
-extern _X_EXPORT Bool miFillGeneralPoly(
- DrawablePtr /*dst*/,
- GCPtr /*pgc*/,
- int /*count*/,
- DDXPointPtr /*ptsIn*/
-);
-
-/* mipolypnt.c */
-
-extern _X_EXPORT void miPolyPoint(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*mode*/,
- int /*npt*/,
- xPoint * /*pptInit*/
-);
-
-/* mipolyrect.c */
-
-extern _X_EXPORT void miPolyRectangle(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*nrects*/,
- xRectangle * /*pRects*/
-);
-
-/* mipolyseg.c */
-
-extern _X_EXPORT void miPolySegment(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*nseg*/,
- xSegment * /*pSegs*/
-);
-
-/* mipolytext.c */
-
-extern _X_EXPORT int miPolyText8(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- int /*count*/,
- char * /*chars*/
-);
-
-extern _X_EXPORT int miPolyText16(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- int /*count*/,
- unsigned short * /*chars*/
-);
-
-extern _X_EXPORT void miImageText8(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- int /*count*/,
- char * /*chars*/
-);
-
-extern _X_EXPORT void miImageText16(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*x*/,
- int /*y*/,
- int /*count*/,
- unsigned short * /*chars*/
-);
-
-/* mipushpxl.c */
-
-extern _X_EXPORT void miPushPixels(
- GCPtr /*pGC*/,
- PixmapPtr /*pBitMap*/,
- DrawablePtr /*pDrawable*/,
- int /*dx*/,
- int /*dy*/,
- int /*xOrg*/,
- int /*yOrg*/
-);
-
-/* miscrinit.c */
-
-extern _X_EXPORT Bool miModifyPixmapHeader(
- PixmapPtr /*pPixmap*/,
- int /*width*/,
- int /*height*/,
- int /*depth*/,
- int /*bitsPerPixel*/,
- int /*devKind*/,
- pointer /*pPixData*/
-);
-
-extern _X_EXPORT Bool miCreateScreenResources(
- ScreenPtr /*pScreen*/
-);
-
-extern _X_EXPORT Bool miScreenDevPrivateInit(
- ScreenPtr /*pScreen*/,
- int /*width*/,
- pointer /*pbits*/
-);
-
-extern _X_EXPORT Bool miScreenInit(
- ScreenPtr /*pScreen*/,
- pointer /*pbits*/,
- int /*xsize*/,
- int /*ysize*/,
- int /*dpix*/,
- int /*dpiy*/,
- int /*width*/,
- int /*rootDepth*/,
- int /*numDepths*/,
- DepthPtr /*depths*/,
- VisualID /*rootVisual*/,
- int /*numVisuals*/,
- VisualPtr /*visuals*/
-);
-
-/* mivaltree.c */
-
-extern _X_EXPORT int miShapedWindowIn(
- RegionPtr /*universe*/,
- RegionPtr /*bounding*/,
- BoxPtr /*rect*/,
- int /*x*/,
- int /*y*/
-);
-
-typedef void
-(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
-
-typedef RegionPtr
-(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
-
-extern _X_EXPORT void
-miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
- GetRedirectBorderClipProcPtr getBorderClip);
-
-extern _X_EXPORT int miValidateTree(
- WindowPtr /*pParent*/,
- WindowPtr /*pChild*/,
- VTKind /*kind*/
-);
-
-extern _X_EXPORT void miWideLine(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*mode*/,
- int /*npt*/,
- DDXPointPtr /*pPts*/
-);
-
-extern _X_EXPORT void miWideDash(
- DrawablePtr /*pDrawable*/,
- GCPtr /*pGC*/,
- int /*mode*/,
- int /*npt*/,
- DDXPointPtr /*pPts*/
-);
-
-/* miwindow.c */
-
-extern _X_EXPORT void miClearToBackground(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- int /*w*/,
- int /*h*/,
- Bool /*generateExposures*/
-);
-
-extern _X_EXPORT void miMarkWindow(
- WindowPtr /*pWin*/
-);
-
-extern _X_EXPORT Bool miMarkOverlappedWindows(
- WindowPtr /*pWin*/,
- WindowPtr /*pFirst*/,
- WindowPtr * /*ppLayerWin*/
-);
-
-extern _X_EXPORT void miHandleValidateExposures(
- WindowPtr /*pWin*/
-);
-
-extern _X_EXPORT void miMoveWindow(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- WindowPtr /*pNextSib*/,
- VTKind /*kind*/
-);
-
-extern _X_EXPORT void miSlideAndSizeWindow(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- unsigned int /*w*/,
- unsigned int /*h*/,
- WindowPtr /*pSib*/
-);
-
-extern _X_EXPORT WindowPtr miGetLayerWindow(
- WindowPtr /*pWin*/
-);
-
-extern _X_EXPORT void miSetShape(
- WindowPtr /*pWin*/,
- int /*kind*/
-);
-
-extern _X_EXPORT void miChangeBorderWidth(
- WindowPtr /*pWin*/,
- unsigned int /*width*/
-);
-
-extern _X_EXPORT void miMarkUnrealizedWindow(
- WindowPtr /*pChild*/,
- WindowPtr /*pWin*/,
- Bool /*fromConfigure*/
-);
-
-extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth);
-
-/* mizerarc.c */
-
-extern _X_EXPORT void miZeroPolyArc(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*narcs*/,
- xArc * /*parcs*/
-);
-
-/* mizerline.c */
-
-extern _X_EXPORT void miZeroLine(
- DrawablePtr /*dst*/,
- GCPtr /*pgc*/,
- int /*mode*/,
- int /*nptInit*/,
- DDXPointRec * /*pptInit*/
-);
-
-extern _X_EXPORT void miZeroDashLine(
- DrawablePtr /*dst*/,
- GCPtr /*pgc*/,
- int /*mode*/,
- int /*nptInit*/,
- DDXPointRec * /*pptInit*/
-);
-
-extern _X_EXPORT void miPolyFillArc(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- int /*narcs*/,
- xArc * /*parcs*/
-);
-
-#endif /* MI_H */
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef MI_H +#define MI_H +#include <X11/X.h> +#include "region.h" +#include "validate.h" +#include "window.h" +#include "gc.h" +#include <X11/fonts/font.h> +#include "input.h" +#include "cursor.h" +#include "privates.h" +#include "colormap.h" +#include "events.h" + +#define MiBits CARD32 + +typedef struct _miDash *miDashPtr; +#define EVEN_DASH 0 +#define ODD_DASH ~0 + +/* miarc.c */ + +extern _X_EXPORT void miPolyArc( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +); + +/* mibitblt.c */ + +extern _X_EXPORT RegionPtr miCopyArea( + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr /*pGC*/, + int /*xIn*/, + int /*yIn*/, + int /*widthSrc*/, + int /*heightSrc*/, + int /*xOut*/, + int /*yOut*/ +); + +extern _X_EXPORT RegionPtr miCopyPlane( + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*bitPlane*/ +); + +extern _X_EXPORT void miGetImage( + DrawablePtr /*pDraw*/, + int /*sx*/, + int /*sy*/, + int /*w*/, + int /*h*/, + unsigned int /*format*/, + unsigned long /*planeMask*/, + char * /*pdstLine*/ +); + +extern _X_EXPORT void miPutImage( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*depth*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*leftPad*/, + int /*format*/, + char * /*pImage*/ +); + +/* micopy.c */ + +#define miGetCompositeClip(pGC) ((pGC)->pCompositeClip) + +typedef void (*miCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +miCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + miCopyProc copyProc, + Pixel bitPlane, + void *closure); + +extern _X_EXPORT RegionPtr +miDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + miCopyProc copyProc, + Pixel bitplane, + void *closure); + +/* micursor.c */ + +extern _X_EXPORT void miRecolorCursor( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScr*/, + CursorPtr /*pCurs*/, + Bool /*displayed*/ +); + +/* midash.c */ + +extern _X_EXPORT void miStepDash( + int /*dist*/, + int * /*pDashIndex*/, + unsigned char * /*pDash*/, + int /*numInDashList*/, + int * /*pDashOffset*/ +); + +/* mieq.c */ + + +#ifndef INPUT_H +typedef struct _DeviceRec *DevicePtr; +#endif + +extern _X_EXPORT Bool mieqInit( + void +); + +extern _X_EXPORT void mieqFini(void); + +extern _X_EXPORT void mieqEnqueue( + DeviceIntPtr /*pDev*/, + InternalEvent* /*e*/ +); + +extern _X_EXPORT void mieqSwitchScreen( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + Bool /*set_dequeue_screen*/ +); + +extern _X_EXPORT void mieqProcessDeviceEvent( + DeviceIntPtr /* dev*/, + InternalEvent* /* event */, + ScreenPtr /* screen*/ +); + +extern _X_EXPORT void mieqProcessInputEvents( + void +); + +extern DeviceIntPtr CopyGetMasterEvent( + DeviceIntPtr /* sdev */, + InternalEvent* /* original */, + InternalEvent* /* copy */ +); + +/** + * Custom input event handler. If you need to process input events in some + * other way than the default path, register an input event handler for the + * given internal event type. + */ +typedef void (*mieqHandler)(int screen, InternalEvent* event, DeviceIntPtr dev); +void _X_EXPORT mieqSetHandler(int event, mieqHandler handler); + +/* miexpose.c */ + +extern _X_EXPORT RegionPtr miHandleExposures( + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*plane*/ +); + +extern _X_EXPORT void miSendGraphicsExpose( + ClientPtr /*client*/, + RegionPtr /*pRgn*/, + XID /*drawable*/, + int /*major*/, + int /*minor*/ +); + +extern _X_EXPORT void miSendExposures( + WindowPtr /*pWin*/, + RegionPtr /*pRgn*/, + int /*dx*/, + int /*dy*/ +); + +extern _X_EXPORT void miWindowExposures( + WindowPtr /*pWin*/, + RegionPtr /*prgn*/, + RegionPtr /*other_exposed*/ +); + +extern _X_EXPORT void miPaintWindow( + WindowPtr /*pWin*/, + RegionPtr /*prgn*/, + int /*what*/ +); + +extern _X_EXPORT void miClearDrawable( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/ +); + +/* mifillrct.c */ + +extern _X_EXPORT void miPolyFillRect( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nrectFill*/, + xRectangle * /*prectInit*/ +); + +/* miglblt.c */ + +extern _X_EXPORT void miPolyGlyphBlt( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +); + +extern _X_EXPORT void miImageGlyphBlt( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +); + +/* mipoly.c */ + +extern _X_EXPORT void miFillPolygon( + DrawablePtr /*dst*/, + GCPtr /*pgc*/, + int /*shape*/, + int /*mode*/, + int /*count*/, + DDXPointPtr /*pPts*/ +); + +/* mipolycon.c */ + +extern _X_EXPORT Bool miFillConvexPoly( + DrawablePtr /*dst*/, + GCPtr /*pgc*/, + int /*count*/, + DDXPointPtr /*ptsIn*/ +); + +/* mipolygen.c */ + +extern _X_EXPORT Bool miFillGeneralPoly( + DrawablePtr /*dst*/, + GCPtr /*pgc*/, + int /*count*/, + DDXPointPtr /*ptsIn*/ +); + +/* mipolypnt.c */ + +extern _X_EXPORT void miPolyPoint( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + xPoint * /*pptInit*/ +); + +/* mipolyrect.c */ + +extern _X_EXPORT void miPolyRectangle( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*nrects*/, + xRectangle * /*pRects*/ +); + +/* mipolyseg.c */ + +extern _X_EXPORT void miPolySegment( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegs*/ +); + +/* mipolytext.c */ + +extern _X_EXPORT int miPolyText8( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + char * /*chars*/ +); + +extern _X_EXPORT int miPolyText16( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + unsigned short * /*chars*/ +); + +extern _X_EXPORT void miImageText8( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + char * /*chars*/ +); + +extern _X_EXPORT void miImageText16( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + unsigned short * /*chars*/ +); + +/* mipushpxl.c */ + +extern _X_EXPORT void miPushPixels( + GCPtr /*pGC*/, + PixmapPtr /*pBitMap*/, + DrawablePtr /*pDrawable*/, + int /*dx*/, + int /*dy*/, + int /*xOrg*/, + int /*yOrg*/ +); + +/* miscrinit.c */ + +extern _X_EXPORT Bool miModifyPixmapHeader( + PixmapPtr /*pPixmap*/, + int /*width*/, + int /*height*/, + int /*depth*/, + int /*bitsPerPixel*/, + int /*devKind*/, + pointer /*pPixData*/ +); + +extern _X_EXPORT Bool miCreateScreenResources( + ScreenPtr /*pScreen*/ +); + +extern _X_EXPORT Bool miScreenDevPrivateInit( + ScreenPtr /*pScreen*/, + int /*width*/, + pointer /*pbits*/ +); + +extern _X_EXPORT Bool miScreenInit( + ScreenPtr /*pScreen*/, + pointer /*pbits*/, + int /*xsize*/, + int /*ysize*/, + int /*dpix*/, + int /*dpiy*/, + int /*width*/, + int /*rootDepth*/, + int /*numDepths*/, + DepthPtr /*depths*/, + VisualID /*rootVisual*/, + int /*numVisuals*/, + VisualPtr /*visuals*/ +); + +/* mivaltree.c */ + +extern _X_EXPORT int miShapedWindowIn( + RegionPtr /*universe*/, + RegionPtr /*bounding*/, + BoxPtr /*rect*/, + int /*x*/, + int /*y*/ +); + +typedef void +(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion); + +typedef RegionPtr +(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow); + +extern _X_EXPORT void +miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, + GetRedirectBorderClipProcPtr getBorderClip); + +extern _X_EXPORT int miValidateTree( + WindowPtr /*pParent*/, + WindowPtr /*pChild*/, + VTKind /*kind*/ +); + +extern _X_EXPORT void miWideLine( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pPts*/ +); + +extern _X_EXPORT void miWideDash( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pPts*/ +); + +/* miwindow.c */ + +extern _X_EXPORT void miClearToBackground( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + Bool /*generateExposures*/ +); + +extern _X_EXPORT void miMarkWindow( + WindowPtr /*pWin*/ +); + +extern _X_EXPORT Bool miMarkOverlappedWindows( + WindowPtr /*pWin*/, + WindowPtr /*pFirst*/, + WindowPtr * /*ppLayerWin*/ +); + +extern _X_EXPORT void miHandleValidateExposures( + WindowPtr /*pWin*/ +); + +extern _X_EXPORT void miMoveWindow( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + WindowPtr /*pNextSib*/, + VTKind /*kind*/ +); + +extern _X_EXPORT void miSlideAndSizeWindow( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + unsigned int /*w*/, + unsigned int /*h*/, + WindowPtr /*pSib*/ +); + +extern _X_EXPORT WindowPtr miGetLayerWindow( + WindowPtr /*pWin*/ +); + +extern _X_EXPORT void miSetShape( + WindowPtr /*pWin*/, + int /*kind*/ +); + +extern _X_EXPORT void miChangeBorderWidth( + WindowPtr /*pWin*/, + unsigned int /*width*/ +); + +extern _X_EXPORT void miMarkUnrealizedWindow( + WindowPtr /*pChild*/, + WindowPtr /*pWin*/, + Bool /*fromConfigure*/ +); + +extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth); + +/* mizerarc.c */ + +extern _X_EXPORT void miZeroPolyArc( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +); + +/* mizerline.c */ + +extern _X_EXPORT void miZeroLine( + DrawablePtr /*dst*/, + GCPtr /*pgc*/, + int /*mode*/, + int /*nptInit*/, + DDXPointRec * /*pptInit*/ +); + +extern _X_EXPORT void miZeroDashLine( + DrawablePtr /*dst*/, + GCPtr /*pgc*/, + int /*mode*/, + int /*nptInit*/, + DDXPointRec * /*pptInit*/ +); + +extern _X_EXPORT void miPolyFillArc( + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +); + +#endif /* MI_H */ diff --git a/xorg-server/mi/mieq.c b/xorg-server/mi/mieq.c index fc3738a41..b75bde9de 100644 --- a/xorg-server/mi/mieq.c +++ b/xorg-server/mi/mieq.c @@ -209,14 +209,29 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) #endif } +/** + * Changes the screen reference events are being enqueued from. + * Input events are enqueued with a screen reference and dequeued and + * processed with a (potentially different) screen reference. + * This function is called whenever a new event has changed screen but is + * still logically on the previous screen as seen by the client. + * This usually happens whenever the visible cursor moves across screen + * boundaries during event generation, before the same event is processed + * and sent down the wire. + * + * @param pDev The device that triggered a screen change. + * @param pScreen The new screen events are being enqueued for. + * @param set_dequeue_screen If TRUE, pScreen is set as both enqueue screen + * and dequeue screen. + */ void -mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool fromDIX) +mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool set_dequeue_screen) { #ifdef XQUARTZ pthread_mutex_lock(&miEventQueueMutex); #endif EnqueueScreen(pDev) = pScreen; - if (fromDIX) + if (set_dequeue_screen) DequeueScreen(pDev) = pScreen; #ifdef XQUARTZ pthread_mutex_unlock(&miEventQueueMutex); diff --git a/xorg-server/mi/mipointer.c b/xorg-server/mi/mipointer.c index 7680ca19b..670f63b6e 100644 --- a/xorg-server/mi/mipointer.c +++ b/xorg-server/mi/mipointer.c @@ -569,9 +569,9 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) - * @param[in,out] x The x coordiante in screen coordinates (in regards to total + * @param[in,out] x The x coordinate in screen coordinates (in regards to total * desktop size) - * @param[in,out] y The y coordiante in screen coordinates (in regards to total + * @param[in,out] y The y coordinate in screen coordinates (in regards to total * desktop size) */ void @@ -603,7 +603,7 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); - /* Smash the confine to the new screen */ + /* Smash the confine to the new screen */ pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; } @@ -622,8 +622,8 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y); - if (pPointer->x == *x && pPointer->y == *y && - pPointer->pScreen == pScreen) + if (pPointer->x == *x && pPointer->y == *y && + pPointer->pScreen == pScreen) return; miPointerMoveNoEvent(pDev, pScreen, *x, *y); diff --git a/xorg-server/mi/mipointer.h b/xorg-server/mi/mipointer.h index 426ef1650..c4265f9d8 100644 --- a/xorg-server/mi/mipointer.h +++ b/xorg-server/mi/mipointer.h @@ -1,154 +1,154 @@ -/*
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-*/
-
-#ifndef MIPOINTER_H
-#define MIPOINTER_H
-
-#include "cursor.h"
-#include "input.h"
-#include "privates.h"
-
-typedef struct _miPointerSpriteFuncRec {
- Bool (*RealizeCursor)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */,
- CursorPtr /* pCurs */
- );
- Bool (*UnrealizeCursor)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */,
- CursorPtr /* pCurs */
- );
- void (*SetCursor)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */,
- CursorPtr /* pCurs */,
- int /* x */,
- int /* y */
- );
- void (*MoveCursor)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */,
- int /* x */,
- int /* y */
- );
- Bool (*DeviceCursorInitialize)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */
- );
- void (*DeviceCursorCleanup)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */
- );
-} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
-
-typedef struct _miPointerScreenFuncRec {
- Bool (*CursorOffScreen)(
- ScreenPtr* /* ppScr */,
- int* /* px */,
- int* /* py */
- );
- void (*CrossScreen)(
- ScreenPtr /* pScr */,
- int /* entering */
- );
- void (*WarpCursor)(
- DeviceIntPtr /*pDev*/,
- ScreenPtr /* pScr */,
- int /* x */,
- int /* y */
- );
- void (*EnqueueEvent)(
- DeviceIntPtr /* pDev */,
- InternalEvent* /* event */
- );
- void (*NewEventScreen)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScr */,
- Bool /* fromDIX */
- );
-} miPointerScreenFuncRec, *miPointerScreenFuncPtr;
-
-extern _X_EXPORT Bool miDCInitialize(
- ScreenPtr /*pScreen*/,
- miPointerScreenFuncPtr /*screenFuncs*/
-);
-
-extern _X_EXPORT Bool miPointerInitialize(
- ScreenPtr /*pScreen*/,
- miPointerSpriteFuncPtr /*spriteFuncs*/,
- miPointerScreenFuncPtr /*screenFuncs*/,
- Bool /*waitForUpdate*/
-);
-
-extern _X_EXPORT void miPointerWarpCursor(
- DeviceIntPtr /*pDev*/,
- ScreenPtr /*pScreen*/,
- int /*x*/,
- int /*y*/
-);
-
-/* Deprecated in favour of miPointerGetScreen. */
-extern _X_EXPORT ScreenPtr miPointerCurrentScreen(
- void
-) _X_DEPRECATED;
-
-extern _X_EXPORT ScreenPtr miPointerGetScreen(
- DeviceIntPtr pDev);
-extern _X_EXPORT void miPointerSetScreen(
- DeviceIntPtr pDev,
- int screen_num,
- int x,
- int y);
-
-/* Returns the current cursor position. */
-extern _X_EXPORT void miPointerGetPosition(
- DeviceIntPtr pDev,
- int *x,
- int *y);
-
-/* Moves the cursor to the specified position. May clip the co-ordinates:
- * x and y are modified in-place. */
-extern _X_EXPORT void miPointerSetPosition(
- DeviceIntPtr pDev,
- int mode,
- int *x,
- int *y);
-
-extern _X_EXPORT void miPointerUpdateSprite(
- DeviceIntPtr pDev);
-
-/* Sets whether the sprite should be updated immediately on pointer moves */
-extern _X_EXPORT Bool miPointerSetWaitForUpdate(
- ScreenPtr pScreen,
- Bool wait);
-
-extern _X_EXPORT DevPrivateKeyRec miPointerPrivKeyRec;
-#define miPointerPrivKey (&miPointerPrivKeyRec)
-
-extern _X_EXPORT DevPrivateKeyRec miPointerScreenKeyRec;
-#define miPointerScreenKey (&miPointerScreenKeyRec)
-
-#endif /* MIPOINTER_H */
+/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +#ifndef MIPOINTER_H +#define MIPOINTER_H + +#include "cursor.h" +#include "input.h" +#include "privates.h" + +typedef struct _miPointerSpriteFuncRec { + Bool (*RealizeCursor)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */, + CursorPtr /* pCurs */ + ); + Bool (*UnrealizeCursor)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */, + CursorPtr /* pCurs */ + ); + void (*SetCursor)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */, + CursorPtr /* pCurs */, + int /* x */, + int /* y */ + ); + void (*MoveCursor)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */, + int /* x */, + int /* y */ + ); + Bool (*DeviceCursorInitialize)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */ + ); + void (*DeviceCursorCleanup)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */ + ); +} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr; + +typedef struct _miPointerScreenFuncRec { + Bool (*CursorOffScreen)( + ScreenPtr* /* ppScr */, + int* /* px */, + int* /* py */ + ); + void (*CrossScreen)( + ScreenPtr /* pScr */, + int /* entering */ + ); + void (*WarpCursor)( + DeviceIntPtr /*pDev*/, + ScreenPtr /* pScr */, + int /* x */, + int /* y */ + ); + void (*EnqueueEvent)( + DeviceIntPtr /* pDev */, + InternalEvent* /* event */ + ); + void (*NewEventScreen)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScr */, + Bool /* set_dequeue_screen */ + ); +} miPointerScreenFuncRec, *miPointerScreenFuncPtr; + +extern _X_EXPORT Bool miDCInitialize( + ScreenPtr /*pScreen*/, + miPointerScreenFuncPtr /*screenFuncs*/ +); + +extern _X_EXPORT Bool miPointerInitialize( + ScreenPtr /*pScreen*/, + miPointerSpriteFuncPtr /*spriteFuncs*/, + miPointerScreenFuncPtr /*screenFuncs*/, + Bool /*waitForUpdate*/ +); + +extern _X_EXPORT void miPointerWarpCursor( + DeviceIntPtr /*pDev*/, + ScreenPtr /*pScreen*/, + int /*x*/, + int /*y*/ +); + +/* Deprecated in favour of miPointerGetScreen. */ +extern _X_EXPORT ScreenPtr miPointerCurrentScreen( + void +) _X_DEPRECATED; + +extern _X_EXPORT ScreenPtr miPointerGetScreen( + DeviceIntPtr pDev); +extern _X_EXPORT void miPointerSetScreen( + DeviceIntPtr pDev, + int screen_num, + int x, + int y); + +/* Returns the current cursor position. */ +extern _X_EXPORT void miPointerGetPosition( + DeviceIntPtr pDev, + int *x, + int *y); + +/* Moves the cursor to the specified position. May clip the co-ordinates: + * x and y are modified in-place. */ +extern _X_EXPORT void miPointerSetPosition( + DeviceIntPtr pDev, + int mode, + int *x, + int *y); + +extern _X_EXPORT void miPointerUpdateSprite( + DeviceIntPtr pDev); + +/* Sets whether the sprite should be updated immediately on pointer moves */ +extern _X_EXPORT Bool miPointerSetWaitForUpdate( + ScreenPtr pScreen, + Bool wait); + +extern _X_EXPORT DevPrivateKeyRec miPointerPrivKeyRec; +#define miPointerPrivKey (&miPointerPrivKeyRec) + +extern _X_EXPORT DevPrivateKeyRec miPointerScreenKeyRec; +#define miPointerScreenKey (&miPointerScreenKeyRec) + +#endif /* MIPOINTER_H */ diff --git a/xorg-server/mi/misprite.c b/xorg-server/mi/misprite.c index 0b47592f0..1025c5a6f 100644 --- a/xorg-server/mi/misprite.c +++ b/xorg-server/mi/misprite.c @@ -1,1042 +1,1037 @@ -/*
- * misprite.c
- *
- * machine independent software sprite routines
- */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "pixmapstr.h"
-#include "input.h"
-#include "mi.h"
-#include "cursorstr.h"
-#include <X11/fonts/font.h>
-#include "scrnintstr.h"
-#include "colormapst.h"
-#include "windowstr.h"
-#include "gcstruct.h"
-#include "mipointer.h"
-#include "misprite.h"
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "inputstr.h"
-#include "damage.h"
-
-typedef struct {
- CursorPtr pCursor;
- int x; /* cursor hotspot */
- int y;
- BoxRec saved; /* saved area from the screen */
- Bool isUp; /* cursor in frame buffer */
- Bool shouldBeUp; /* cursor should be displayed */
- WindowPtr pCacheWin; /* window the cursor last seen in */
- Bool isInCacheWin;
- Bool checkPixels; /* check colormap collision */
- ScreenPtr pScreen;
-} miCursorInfoRec, *miCursorInfoPtr;
-
-/*
- * per screen information
- */
-
-typedef struct {
- /* screen procedures */
- CloseScreenProcPtr CloseScreen;
- GetImageProcPtr GetImage;
- GetSpansProcPtr GetSpans;
- SourceValidateProcPtr SourceValidate;
-
- /* window procedures */
- CopyWindowProcPtr CopyWindow;
-
- /* colormap procedures */
- InstallColormapProcPtr InstallColormap;
- StoreColorsProcPtr StoreColors;
-
- /* os layer procedures */
- ScreenBlockHandlerProcPtr BlockHandler;
-
- /* device cursor procedures */
- DeviceCursorInitializeProcPtr DeviceCursorInitialize;
- DeviceCursorCleanupProcPtr DeviceCursorCleanup;
-
- xColorItem colors[2];
- ColormapPtr pInstalledMap;
- ColormapPtr pColormap;
- VisualPtr pVisual;
- DamagePtr pDamage; /* damage tracking structure */
- Bool damageRegistered;
- int numberOfCursors;
-} miSpriteScreenRec, *miSpriteScreenPtr;
-
-#define SOURCE_COLOR 0
-#define MASK_COLOR 1
-
-/*
- * Overlap BoxPtr and Box elements
- */
-#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
- (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
- ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
-
-/*
- * Overlap BoxPtr, origins, and rectangle
- */
-#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
- BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
-
-/*
- * Overlap BoxPtr, origins and RectPtr
- */
-#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
- ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
- (int)((pRect)->width), (int)((pRect)->height))
-/*
- * Overlap BoxPtr and horizontal span
- */
-#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
-
-#define LINE_SORT(x1,y1,x2,y2) \
-{ int _t; \
- if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
- if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
-
-#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
- BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
-
-
-#define SPRITE_DEBUG_ENABLE 0
-#if SPRITE_DEBUG_ENABLE
-#define SPRITE_DEBUG(x) ErrorF x
-#else
-#define SPRITE_DEBUG(x)
-#endif
-
-#define MISPRITE(dev) \
- (IsFloating(dev) ? \
- (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \
- (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey))
-
-static void
-miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
- if (pScreenPriv->damageRegistered) {
- DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
- pScreenPriv->pDamage);
- pScreenPriv->damageRegistered = 0;
- }
-}
-
-static void
-miSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
- if (!pScreenPriv->damageRegistered) {
- pScreenPriv->damageRegistered = 1;
- DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
- pScreenPriv->pDamage);
- }
-}
-
-static void
-miSpriteIsUp(miCursorInfoPtr pDevCursor)
-{
- pDevCursor->isUp = TRUE;
-}
-
-static void
-miSpriteIsDown(miCursorInfoPtr pDevCursor)
-{
- pDevCursor->isUp = FALSE;
-}
-
-/*
- * screen wrappers
- */
-
-static DevPrivateKeyRec miSpriteScreenKeyRec;
-#define miSpriteScreenKey (&miSpriteScreenKeyRec)
-#define GetSpriteScreen(pScreen) \
- (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey))
-static DevPrivateKeyRec miSpriteDevPrivatesKeyRec;
-#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec)
-
-static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen);
-static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
- int w, int h, unsigned int format,
- unsigned long planemask, char *pdstLine);
-static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans,
- char *pdstStart);
-static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
- int width, int height,
- unsigned int subWindowMode);
-static void miSpriteCopyWindow (WindowPtr pWindow,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc);
-static void miSpriteBlockHandler(int i, pointer blockData,
- pointer pTimeout,
- pointer pReadMask);
-static void miSpriteInstallColormap(ColormapPtr pMap);
-static void miSpriteStoreColors(ColormapPtr pMap, int ndef,
- xColorItem *pdef);
-
-static void miSpriteComputeSaved(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-
-static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-
-#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \
- (pPriv)->field)
-#define SCREEN_EPILOGUE(pPriv, pScreen, field)\
- ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field)
-
-/*
- * pointer-sprite method table
- */
-
-static Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCursor);
-static Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCursor);
-static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCursor, int x, int y);
-static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- int x, int y);
-
-miPointerSpriteFuncRec miSpritePointerFuncs = {
- miSpriteRealizeCursor,
- miSpriteUnrealizeCursor,
- miSpriteSetCursor,
- miSpriteMoveCursor,
- miSpriteDeviceCursorInitialize,
- miSpriteDeviceCursorCleanup,
-};
-
-/*
- * other misc functions
- */
-
-static void miSpriteRemoveCursor(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-static void miSpriteSaveUnderCursor(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-static void miSpriteRestoreCursor(DeviceIntPtr pDev,
- ScreenPtr pScreen);
-
-static void
-miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
- if (!pScreenPriv->BlockHandler) {
- pScreenPriv->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = miSpriteBlockHandler;
- }
-}
-
-static void
-miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
-{
- ScreenPtr pScreen = closure;
- miCursorInfoPtr pCursorInfo;
- DeviceIntPtr pDev;
-
- for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
-
- if (pCursorInfo->isUp &&
- pCursorInfo->pScreen == pScreen &&
- RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT)
- {
- SPRITE_DEBUG(("Damage remove\n"));
- miSpriteRemoveCursor (pDev, pScreen);
- }
- }
- }
-}
-
-/*
- * miSpriteInitialize -- called from device-dependent screen
- * initialization proc after all of the function pointers have
- * been stored in the screen structure.
- */
-
-Bool
-miSpriteInitialize (ScreenPtr pScreen,
- miPointerScreenFuncPtr screenFuncs)
-{
- miSpriteScreenPtr pScreenPriv;
- VisualPtr pVisual;
-
- if (!DamageSetup (pScreen))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec)))
- return FALSE;
-
- pScreenPriv = malloc(sizeof (miSpriteScreenRec));
- if (!pScreenPriv)
- return FALSE;
-
- pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
- NULL,
- DamageReportRawRegion,
- TRUE,
- pScreen,
- pScreen);
-
- if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
- {
- free(pScreenPriv);
- return FALSE;
- }
- for (pVisual = pScreen->visuals;
- pVisual->vid != pScreen->rootVisual;
- pVisual++)
- ;
- pScreenPriv->pVisual = pVisual;
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreenPriv->GetImage = pScreen->GetImage;
- pScreenPriv->GetSpans = pScreen->GetSpans;
- pScreenPriv->SourceValidate = pScreen->SourceValidate;
-
- pScreenPriv->CopyWindow = pScreen->CopyWindow;
-
- pScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreenPriv->StoreColors = pScreen->StoreColors;
-
- pScreenPriv->BlockHandler = NULL;
-
- pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
- pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
-
- pScreenPriv->pInstalledMap = NULL;
- pScreenPriv->pColormap = NULL;
- pScreenPriv->colors[SOURCE_COLOR].red = 0;
- pScreenPriv->colors[SOURCE_COLOR].green = 0;
- pScreenPriv->colors[SOURCE_COLOR].blue = 0;
- pScreenPriv->colors[MASK_COLOR].red = 0;
- pScreenPriv->colors[MASK_COLOR].green = 0;
- pScreenPriv->colors[MASK_COLOR].blue = 0;
- pScreenPriv->damageRegistered = 0;
- pScreenPriv->numberOfCursors = 0;
-
- dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv);
-
- pScreen->CloseScreen = miSpriteCloseScreen;
- pScreen->GetImage = miSpriteGetImage;
- pScreen->GetSpans = miSpriteGetSpans;
- pScreen->SourceValidate = miSpriteSourceValidate;
-
- pScreen->CopyWindow = miSpriteCopyWindow;
- pScreen->InstallColormap = miSpriteInstallColormap;
- pScreen->StoreColors = miSpriteStoreColors;
-
- return TRUE;
-}
-
-/*
- * Screen wrappers
- */
-
-/*
- * CloseScreen wrapper -- unwrap everything, free the private data
- * and call the wrapped function
- */
-
-static Bool
-miSpriteCloseScreen (int i, ScreenPtr pScreen)
-{
- miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->GetImage = pScreenPriv->GetImage;
- pScreen->GetSpans = pScreenPriv->GetSpans;
- pScreen->SourceValidate = pScreenPriv->SourceValidate;
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- pScreen->StoreColors = pScreenPriv->StoreColors;
-
- DamageDestroy (pScreenPriv->pDamage);
-
- free(pScreenPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void
-miSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format, unsigned long planemask,
- char *pdstLine)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
-
- SCREEN_PROLOGUE (pPriv, pScreen, GetImage);
-
- if (pDrawable->type == DRAWABLE_WINDOW)
- {
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
- ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
- sx, sy, w, h))
- {
- SPRITE_DEBUG (("GetImage remove\n"));
- miSpriteRemoveCursor (pDev, pScreen);
- }
- }
- }
- }
-
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
- format, planemask, pdstLine);
-
- SCREEN_EPILOGUE (pPriv, pScreen, GetImage);
-}
-
-static void
-miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
- int *pwidth, int nspans, char *pdstStart)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
-
- SCREEN_PROLOGUE (pPriv, pScreen, GetSpans);
-
- if (pDrawable->type == DRAWABLE_WINDOW)
- {
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
-
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
- {
- DDXPointPtr pts;
- int *widths;
- int nPts;
- int xorg,
- yorg;
-
- xorg = pDrawable->x;
- yorg = pDrawable->y;
-
- for (pts = ppt, widths = pwidth, nPts = nspans;
- nPts--;
- pts++, widths++)
- {
- if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg,
- pts->x+xorg,*widths))
- {
- SPRITE_DEBUG (("GetSpans remove\n"));
- miSpriteRemoveCursor (pDev, pScreen);
- break;
- }
- }
- }
- }
- }
- }
-
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-
- SCREEN_EPILOGUE (pPriv, pScreen, GetSpans);
-}
-
-static void
-miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width,
- int height, unsigned int subWindowMode)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
-
- SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate);
-
- if (pDrawable->type == DRAWABLE_WINDOW)
- {
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
- ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
- x, y, width, height))
- {
- SPRITE_DEBUG (("SourceValidate remove\n"));
- miSpriteRemoveCursor (pDev, pScreen);
- }
- }
- }
- }
-
- if (pScreen->SourceValidate)
- (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode);
-
- SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate);
-}
-
-static void
-miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
-
- SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow);
-
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- /*
- * Damage will take care of destination check
- */
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
- RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT)
- {
- SPRITE_DEBUG (("CopyWindow remove\n"));
- miSpriteRemoveCursor (pDev, pScreen);
- }
- }
- }
-
- (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
- SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow);
-}
-
-static void
-miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout,
- pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- Bool WorkToDo = FALSE;
-
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- if (pCursorInfo && !pCursorInfo->isUp
- && pCursorInfo->pScreen == pScreen
- && pCursorInfo->shouldBeUp)
- {
- SPRITE_DEBUG (("BlockHandler save"));
- miSpriteSaveUnderCursor (pDev, pScreen);
- }
- }
- }
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- if (pCursorInfo && !pCursorInfo->isUp &&
- pCursorInfo->pScreen == pScreen &&
- pCursorInfo->shouldBeUp)
- {
- SPRITE_DEBUG (("BlockHandler restore\n"));
- miSpriteRestoreCursor (pDev, pScreen);
- if (!pCursorInfo->isUp)
- WorkToDo = TRUE;
- }
- }
- }
-
- SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler);
-
- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-
- if (WorkToDo)
- SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler);
- else
- pPriv->BlockHandler = NULL;
-}
-
-static void
-miSpriteInstallColormap (ColormapPtr pMap)
-{
- ScreenPtr pScreen = pMap->pScreen;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
-
- SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap);
-
- (*pScreen->InstallColormap) (pMap);
-
- SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap);
-
- /* InstallColormap can be called before devices are initialized. */
- pPriv->pInstalledMap = pMap;
- if (pPriv->pColormap != pMap)
- {
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
- for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- pCursorInfo->checkPixels = TRUE;
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
- miSpriteRemoveCursor(pDev, pScreen);
- }
- }
-
- }
-}
-
-static void
-miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
-{
- ScreenPtr pScreen = pMap->pScreen;
- miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
- int i;
- int updated;
- VisualPtr pVisual;
- DeviceIntPtr pDev;
- miCursorInfoPtr pCursorInfo;
-
- SCREEN_PROLOGUE(pPriv, pScreen, StoreColors);
-
- (*pScreen->StoreColors) (pMap, ndef, pdef);
-
- SCREEN_EPILOGUE(pPriv, pScreen, StoreColors);
-
- if (pPriv->pColormap == pMap)
- {
- updated = 0;
- pVisual = pMap->pVisual;
- if (pVisual->class == DirectColor)
- {
- /* Direct color - match on any of the subfields */
-
-#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
-
-#define UpdateDAC(dev, plane,dac,mask) {\
- if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\
- dev->colors[plane].dac = pdef[i].dac; \
- updated = 1; \
- } \
-}
-
-#define CheckDirect(dev, plane) \
- UpdateDAC(dev, plane,red,redMask) \
- UpdateDAC(dev, plane,green,greenMask) \
- UpdateDAC(dev, plane,blue,blueMask)
-
- for (i = 0; i < ndef; i++)
- {
- CheckDirect (pPriv, SOURCE_COLOR)
- CheckDirect (pPriv, MASK_COLOR)
- }
- }
- else
- {
- /* PseudoColor/GrayScale - match on exact pixel */
- for (i = 0; i < ndef; i++)
- {
- if (pdef[i].pixel ==
- pPriv->colors[SOURCE_COLOR].pixel)
- {
- pPriv->colors[SOURCE_COLOR] = pdef[i];
- if (++updated == 2)
- break;
- }
- if (pdef[i].pixel ==
- pPriv->colors[MASK_COLOR].pixel)
- {
- pPriv->colors[MASK_COLOR] = pdef[i];
- if (++updated == 2)
- break;
- }
- }
- }
- if (updated)
- {
- for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
- {
- if (DevHasCursor(pDev))
- {
- pCursorInfo = MISPRITE(pDev);
- pCursorInfo->checkPixels = TRUE;
- if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
- miSpriteRemoveCursor (pDev, pScreen);
- }
- }
- }
- }
-}
-
-static void
-miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
-{
- miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen);
- CursorPtr pCursor;
- xColorItem *sourceColor, *maskColor;
-
- pCursor = pDevCursor->pCursor;
- sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
- maskColor = &pScreenPriv->colors[MASK_COLOR];
- if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
- !(pCursor->foreRed == sourceColor->red &&
- pCursor->foreGreen == sourceColor->green &&
- pCursor->foreBlue == sourceColor->blue &&
- pCursor->backRed == maskColor->red &&
- pCursor->backGreen == maskColor->green &&
- pCursor->backBlue == maskColor->blue))
- {
- pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
- sourceColor->red = pCursor->foreRed;
- sourceColor->green = pCursor->foreGreen;
- sourceColor->blue = pCursor->foreBlue;
- FakeAllocColor (pScreenPriv->pColormap, sourceColor);
- maskColor->red = pCursor->backRed;
- maskColor->green = pCursor->backGreen;
- maskColor->blue = pCursor->backBlue;
- FakeAllocColor (pScreenPriv->pColormap, maskColor);
- /* "free" the pixels right away, don't let this confuse you */
- FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
- FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
- }
-
- pDevCursor->checkPixels = FALSE;
-
-}
-
-/*
- * miPointer interface routines
- */
-
-#define SPRITE_PAD 8
-
-static Bool
-miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- miCursorInfoPtr pCursorInfo;
-
- if (IsFloating(pDev))
- return FALSE;
-
- pCursorInfo = MISPRITE(pDev);
-
- if (pCursor == pCursorInfo->pCursor)
- pCursorInfo->checkPixels = TRUE;
-
- return miDCRealizeCursor(pScreen, pCursor);
-}
-
-static Bool
-miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- return miDCUnrealizeCursor(pScreen, pCursor);
-}
-
-static void
-miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCursor, int x, int y)
-{
- miCursorInfoPtr pPointer;
- miSpriteScreenPtr pScreenPriv;
-
- if (IsFloating(pDev))
- return;
-
- pPointer = MISPRITE(pDev);
- pScreenPriv = GetSpriteScreen(pScreen);
-
- if (!pCursor)
- {
- if (pPointer->shouldBeUp)
- --pScreenPriv->numberOfCursors;
- pPointer->shouldBeUp = FALSE;
- if (pPointer->isUp)
- miSpriteRemoveCursor (pDev, pScreen);
- if (pScreenPriv->numberOfCursors == 0)
- miSpriteDisableDamage(pScreen, pScreenPriv);
- pPointer->pCursor = 0;
- return;
- }
- if (!pPointer->shouldBeUp)
- pScreenPriv->numberOfCursors++;
- pPointer->shouldBeUp = TRUE;
- if (!pPointer->isUp)
- miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
- if (pPointer->x == x &&
- pPointer->y == y &&
- pPointer->pCursor == pCursor &&
- !pPointer->checkPixels)
- {
- return;
- }
- pPointer->x = x;
- pPointer->y = y;
- pPointer->pCacheWin = NullWindow;
- if (pPointer->checkPixels || pPointer->pCursor != pCursor)
- {
- pPointer->pCursor = pCursor;
- miSpriteFindColors (pPointer, pScreen);
- }
- if (pPointer->isUp) {
- /* TODO: reimplement flicker-free MoveCursor */
- SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id));
- miSpriteRemoveCursor (pDev, pScreen);
- }
-
- if (!pPointer->isUp && pPointer->pCursor)
- {
- SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id));
- miSpriteSaveUnderCursor(pDev, pScreen);
- miSpriteRestoreCursor (pDev, pScreen);
- }
-
-}
-
-static void
-miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- CursorPtr pCursor;
-
- if (IsFloating(pDev))
- return;
-
- pCursor = MISPRITE(pDev)->pCursor;
-
- miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
-}
-
-
-static Bool
-miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- int ret = miDCDeviceInitialize(pDev, pScreen);
-
- if (ret)
- {
- miCursorInfoPtr pCursorInfo;
- pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey);
- pCursorInfo->pCursor = NULL;
- pCursorInfo->x = 0;
- pCursorInfo->y = 0;
- pCursorInfo->isUp = FALSE;
- pCursorInfo->shouldBeUp = FALSE;
- pCursorInfo->pCacheWin = NullWindow;
- pCursorInfo->isInCacheWin = FALSE;
- pCursorInfo->checkPixels = TRUE;
- pCursorInfo->pScreen = FALSE;
- }
-
- return ret;
-}
-
-static void
-miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- miCursorInfoPtr pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey);
-
- if (DevHasCursor(pDev))
- miDCDeviceCleanup(pDev, pScreen);
-
- memset(pCursorInfo, 0, sizeof(miCursorInfoRec));
-}
-
-/*
- * undraw/draw cursor
- */
-
-static void
-miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- miSpriteScreenPtr pScreenPriv;
- miCursorInfoPtr pCursorInfo;
-
-
- if (IsFloating(pDev))
- return;
-
- DamageDrawInternal (pScreen, TRUE);
- pScreenPriv = GetSpriteScreen(pScreen);
- pCursorInfo = MISPRITE(pDev);
-
- miSpriteIsDown(pCursorInfo);
- miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
- pCursorInfo->pCacheWin = NullWindow;
- miSpriteDisableDamage(pScreen, pScreenPriv);
- if (!miDCRestoreUnderCursor(pDev,
- pScreen,
- pCursorInfo->saved.x1,
- pCursorInfo->saved.y1,
- pCursorInfo->saved.x2 -
- pCursorInfo->saved.x1,
- pCursorInfo->saved.y2 -
- pCursorInfo->saved.y1))
- {
- miSpriteIsUp(pCursorInfo);
- }
- miSpriteEnableDamage(pScreen, pScreenPriv);
- DamageDrawInternal (pScreen, FALSE);
-}
-
-/*
- * Called from the block handler, saves area under cursor
- * before waiting for something to do.
- */
-
-static void
-miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- miSpriteScreenPtr pScreenPriv;
- int x, y;
- CursorPtr pCursor;
- miCursorInfoPtr pCursorInfo;
-
- if (IsFloating(pDev))
- return;
-
- DamageDrawInternal (pScreen, TRUE);
- pScreenPriv = GetSpriteScreen(pScreen);
- pCursorInfo = MISPRITE(pDev);
-
- miSpriteComputeSaved (pDev, pScreen);
- pCursor = pCursorInfo->pCursor;
-
- x = pCursorInfo->x - (int)pCursor->bits->xhot;
- y = pCursorInfo->y - (int)pCursor->bits->yhot;
- miSpriteDisableDamage(pScreen, pScreenPriv);
-
- miDCSaveUnderCursor(pDev,
- pScreen,
- pCursorInfo->saved.x1,
- pCursorInfo->saved.y1,
- pCursorInfo->saved.x2 -
- pCursorInfo->saved.x1,
- pCursorInfo->saved.y2 -
- pCursorInfo->saved.y1);
- SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id));
- miSpriteEnableDamage(pScreen, pScreenPriv);
- DamageDrawInternal (pScreen, FALSE);
-}
-
-
-/*
- * Called from the block handler, restores the cursor
- * before waiting for something to do.
- */
-
-static void
-miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- miSpriteScreenPtr pScreenPriv;
- int x, y;
- CursorPtr pCursor;
- miCursorInfoPtr pCursorInfo;
-
- if (IsFloating(pDev))
- return;
-
- DamageDrawInternal (pScreen, TRUE);
- pScreenPriv = GetSpriteScreen(pScreen);
- pCursorInfo = MISPRITE(pDev);
-
- miSpriteComputeSaved (pDev, pScreen);
- pCursor = pCursorInfo->pCursor;
-
- x = pCursorInfo->x - (int)pCursor->bits->xhot;
- y = pCursorInfo->y - (int)pCursor->bits->yhot;
- miSpriteDisableDamage(pScreen, pScreenPriv);
- SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id));
- if (pCursorInfo->checkPixels)
- miSpriteFindColors (pCursorInfo, pScreen);
- if (miDCPutUpCursor(pDev, pScreen,
- pCursor, x, y,
- pScreenPriv->colors[SOURCE_COLOR].pixel,
- pScreenPriv->colors[MASK_COLOR].pixel))
- {
- miSpriteIsUp(pCursorInfo);
- pCursorInfo->pScreen = pScreen;
- }
- miSpriteEnableDamage(pScreen, pScreenPriv);
- DamageDrawInternal (pScreen, FALSE);
-}
-
-/*
- * compute the desired area of the screen to save
- */
-
-static void
-miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- int x, y, w, h;
- int wpad, hpad;
- CursorPtr pCursor;
- miCursorInfoPtr pCursorInfo;
-
- if (IsFloating(pDev))
- return;
-
- pCursorInfo = MISPRITE(pDev);
-
- pCursor = pCursorInfo->pCursor;
- x = pCursorInfo->x - (int)pCursor->bits->xhot;
- y = pCursorInfo->y - (int)pCursor->bits->yhot;
- w = pCursor->bits->width;
- h = pCursor->bits->height;
- wpad = SPRITE_PAD;
- hpad = SPRITE_PAD;
- pCursorInfo->saved.x1 = x - wpad;
- pCursorInfo->saved.y1 = y - hpad;
- pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2;
- pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2;
-}
-
+/* + * misprite.c + * + * machine independent software sprite routines + */ + +/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "pixmapstr.h" +#include "input.h" +#include "mi.h" +#include "cursorstr.h" +#include <X11/fonts/font.h> +#include "scrnintstr.h" +#include "colormapst.h" +#include "windowstr.h" +#include "gcstruct.h" +#include "mipointer.h" +#include "misprite.h" +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "inputstr.h" +#include "damage.h" + +typedef struct { + CursorPtr pCursor; + int x; /* cursor hotspot */ + int y; + BoxRec saved; /* saved area from the screen */ + Bool isUp; /* cursor in frame buffer */ + Bool shouldBeUp; /* cursor should be displayed */ + WindowPtr pCacheWin; /* window the cursor last seen in */ + Bool isInCacheWin; + Bool checkPixels; /* check colormap collision */ + ScreenPtr pScreen; +} miCursorInfoRec, *miCursorInfoPtr; + +/* + * per screen information + */ + +typedef struct { + /* screen procedures */ + CloseScreenProcPtr CloseScreen; + GetImageProcPtr GetImage; + GetSpansProcPtr GetSpans; + SourceValidateProcPtr SourceValidate; + + /* window procedures */ + CopyWindowProcPtr CopyWindow; + + /* colormap procedures */ + InstallColormapProcPtr InstallColormap; + StoreColorsProcPtr StoreColors; + + /* os layer procedures */ + ScreenBlockHandlerProcPtr BlockHandler; + + /* device cursor procedures */ + DeviceCursorInitializeProcPtr DeviceCursorInitialize; + DeviceCursorCleanupProcPtr DeviceCursorCleanup; + + xColorItem colors[2]; + ColormapPtr pInstalledMap; + ColormapPtr pColormap; + VisualPtr pVisual; + DamagePtr pDamage; /* damage tracking structure */ + Bool damageRegistered; + int numberOfCursors; +} miSpriteScreenRec, *miSpriteScreenPtr; + +#define SOURCE_COLOR 0 +#define MASK_COLOR 1 + +/* + * Overlap BoxPtr and Box elements + */ +#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ + (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ + ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) + +/* + * Overlap BoxPtr, origins, and rectangle + */ +#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ + BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) + +/* + * Overlap BoxPtr, origins and RectPtr + */ +#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ + ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ + (int)((pRect)->width), (int)((pRect)->height)) +/* + * Overlap BoxPtr and horizontal span + */ +#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) + +#define LINE_SORT(x1,y1,x2,y2) \ +{ int _t; \ + if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ + if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } + +#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ + BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) + + +#define SPRITE_DEBUG_ENABLE 0 +#if SPRITE_DEBUG_ENABLE +#define SPRITE_DEBUG(x) ErrorF x +#else +#define SPRITE_DEBUG(x) +#endif + +#define MISPRITE(dev) \ + (IsFloating(dev) ? \ + (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ + (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) + +static void +miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) +{ + if (pScreenPriv->damageRegistered) { + DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable), + pScreenPriv->pDamage); + pScreenPriv->damageRegistered = 0; + } +} + +static void +miSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) +{ + if (!pScreenPriv->damageRegistered) { + pScreenPriv->damageRegistered = 1; + DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable), + pScreenPriv->pDamage); + } +} + +static void +miSpriteIsUp(miCursorInfoPtr pDevCursor) +{ + pDevCursor->isUp = TRUE; +} + +static void +miSpriteIsDown(miCursorInfoPtr pDevCursor) +{ + pDevCursor->isUp = FALSE; +} + +/* + * screen wrappers + */ + +static DevPrivateKeyRec miSpriteScreenKeyRec; +#define miSpriteScreenKey (&miSpriteScreenKeyRec) +#define GetSpriteScreen(pScreen) \ + (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey)) +static DevPrivateKeyRec miSpriteDevPrivatesKeyRec; +#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) + +static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); +static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, + int w, int h, unsigned int format, + unsigned long planemask, char *pdstLine); +static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, + DDXPointPtr ppt, int *pwidth, int nspans, + char *pdstStart); +static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, + int width, int height, + unsigned int subWindowMode); +static void miSpriteCopyWindow (WindowPtr pWindow, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); +static void miSpriteBlockHandler(int i, pointer blockData, + pointer pTimeout, + pointer pReadMask); +static void miSpriteInstallColormap(ColormapPtr pMap); +static void miSpriteStoreColors(ColormapPtr pMap, int ndef, + xColorItem *pdef); + +static void miSpriteComputeSaved(DeviceIntPtr pDev, + ScreenPtr pScreen); + +static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, + ScreenPtr pScreen); + +#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ + (pPriv)->field) +#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ + ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) + +/* + * pointer-sprite method table + */ + +static Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y); +static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y); + +miPointerSpriteFuncRec miSpritePointerFuncs = { + miSpriteRealizeCursor, + miSpriteUnrealizeCursor, + miSpriteSetCursor, + miSpriteMoveCursor, + miSpriteDeviceCursorInitialize, + miSpriteDeviceCursorCleanup, +}; + +/* + * other misc functions + */ + +static void miSpriteRemoveCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteRestoreCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); + +static void +miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) +{ + if (!pScreenPriv->BlockHandler) { + pScreenPriv->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = miSpriteBlockHandler; + } +} + +static void +miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) +{ + ScreenPtr pScreen = closure; + miCursorInfoPtr pCursorInfo; + DeviceIntPtr pDev; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + + if (pCursorInfo->isUp && + pCursorInfo->pScreen == pScreen && + RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) + { + SPRITE_DEBUG(("Damage remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } + } +} + +/* + * miSpriteInitialize -- called from device-dependent screen + * initialization proc after all of the function pointers have + * been stored in the screen structure. + */ + +Bool +miSpriteInitialize (ScreenPtr pScreen, + miPointerScreenFuncPtr screenFuncs) +{ + miSpriteScreenPtr pScreenPriv; + VisualPtr pVisual; + + if (!DamageSetup (pScreen)) + return FALSE; + + if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) + return FALSE; + + pScreenPriv = malloc(sizeof (miSpriteScreenRec)); + if (!pScreenPriv) + return FALSE; + + pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, + NULL, + DamageReportRawRegion, + TRUE, + pScreen, + pScreen); + + if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) + { + free(pScreenPriv); + return FALSE; + } + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++) + ; + pScreenPriv->pVisual = pVisual; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreenPriv->GetImage = pScreen->GetImage; + pScreenPriv->GetSpans = pScreen->GetSpans; + pScreenPriv->SourceValidate = pScreen->SourceValidate; + + pScreenPriv->CopyWindow = pScreen->CopyWindow; + + pScreenPriv->InstallColormap = pScreen->InstallColormap; + pScreenPriv->StoreColors = pScreen->StoreColors; + + pScreenPriv->BlockHandler = NULL; + + pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize; + pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup; + + pScreenPriv->pInstalledMap = NULL; + pScreenPriv->pColormap = NULL; + pScreenPriv->colors[SOURCE_COLOR].red = 0; + pScreenPriv->colors[SOURCE_COLOR].green = 0; + pScreenPriv->colors[SOURCE_COLOR].blue = 0; + pScreenPriv->colors[MASK_COLOR].red = 0; + pScreenPriv->colors[MASK_COLOR].green = 0; + pScreenPriv->colors[MASK_COLOR].blue = 0; + pScreenPriv->damageRegistered = 0; + pScreenPriv->numberOfCursors = 0; + + dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv); + + pScreen->CloseScreen = miSpriteCloseScreen; + pScreen->GetImage = miSpriteGetImage; + pScreen->GetSpans = miSpriteGetSpans; + pScreen->SourceValidate = miSpriteSourceValidate; + + pScreen->CopyWindow = miSpriteCopyWindow; + pScreen->InstallColormap = miSpriteInstallColormap; + pScreen->StoreColors = miSpriteStoreColors; + + return TRUE; +} + +/* + * Screen wrappers + */ + +/* + * CloseScreen wrapper -- unwrap everything, free the private data + * and call the wrapped function + */ + +static Bool +miSpriteCloseScreen (int i, ScreenPtr pScreen) +{ + miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->SourceValidate = pScreenPriv->SourceValidate; + pScreen->InstallColormap = pScreenPriv->InstallColormap; + pScreen->StoreColors = pScreenPriv->StoreColors; + + DamageDestroy (pScreenPriv->pDamage); + + free(pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +miSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planemask, + char *pdstLine) +{ + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE (pPriv, pScreen, GetImage); + + if (pDrawable->type == DRAWABLE_WINDOW) + { + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, + sx, sy, w, h)) + { + SPRITE_DEBUG (("GetImage remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } + } + } + + (*pScreen->GetImage) (pDrawable, sx, sy, w, h, + format, planemask, pdstLine); + + SCREEN_EPILOGUE (pPriv, pScreen, GetImage); +} + +static void +miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, + int *pwidth, int nspans, char *pdstStart) +{ + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE (pPriv, pScreen, GetSpans); + + if (pDrawable->type == DRAWABLE_WINDOW) + { + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) + { + DDXPointPtr pts; + int *widths; + int nPts; + int xorg, + yorg; + + xorg = pDrawable->x; + yorg = pDrawable->y; + + for (pts = ppt, widths = pwidth, nPts = nspans; + nPts--; + pts++, widths++) + { + if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, + pts->x+xorg,*widths)) + { + SPRITE_DEBUG (("GetSpans remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + break; + } + } + } + } + } + } + + (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + + SCREEN_EPILOGUE (pPriv, pScreen, GetSpans); +} + +static void +miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, + int height, unsigned int subWindowMode) +{ + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate); + + if (pDrawable->type == DRAWABLE_WINDOW) + { + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, + x, y, width, height)) + { + SPRITE_DEBUG (("SourceValidate remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } + } + } + + if (pScreen->SourceValidate) + (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); + + SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate); +} + +static void +miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow); + + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + /* + * Damage will take care of destination check + */ + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) + { + SPRITE_DEBUG (("CopyWindow remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } + } + + (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); + SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow); +} + +static void +miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + Bool WorkToDo = FALSE; + + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo && !pCursorInfo->isUp + && pCursorInfo->pScreen == pScreen + && pCursorInfo->shouldBeUp) + { + SPRITE_DEBUG (("BlockHandler save")); + miSpriteSaveUnderCursor (pDev, pScreen); + } + } + } + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo && !pCursorInfo->isUp && + pCursorInfo->pScreen == pScreen && + pCursorInfo->shouldBeUp) + { + SPRITE_DEBUG (("BlockHandler restore\n")); + miSpriteRestoreCursor (pDev, pScreen); + if (!pCursorInfo->isUp) + WorkToDo = TRUE; + } + } + } + + SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); + + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + + if (WorkToDo) + SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); + else + pPriv->BlockHandler = NULL; +} + +static void +miSpriteInstallColormap (ColormapPtr pMap) +{ + ScreenPtr pScreen = pMap->pScreen; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); + + (*pScreen->InstallColormap) (pMap); + + SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); + + /* InstallColormap can be called before devices are initialized. */ + pPriv->pInstalledMap = pMap; + if (pPriv->pColormap != pMap) + { + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + pCursorInfo->checkPixels = TRUE; + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) + miSpriteRemoveCursor(pDev, pScreen); + } + } + + } +} + +static void +miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) +{ + ScreenPtr pScreen = pMap->pScreen; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + int i; + int updated; + VisualPtr pVisual; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + + SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); + + (*pScreen->StoreColors) (pMap, ndef, pdef); + + SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); + + if (pPriv->pColormap == pMap) + { + updated = 0; + pVisual = pMap->pVisual; + if (pVisual->class == DirectColor) + { + /* Direct color - match on any of the subfields */ + +#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) + +#define UpdateDAC(dev, plane,dac,mask) {\ + if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ + dev->colors[plane].dac = pdef[i].dac; \ + updated = 1; \ + } \ +} + +#define CheckDirect(dev, plane) \ + UpdateDAC(dev, plane,red,redMask) \ + UpdateDAC(dev, plane,green,greenMask) \ + UpdateDAC(dev, plane,blue,blueMask) + + for (i = 0; i < ndef; i++) + { + CheckDirect (pPriv, SOURCE_COLOR) + CheckDirect (pPriv, MASK_COLOR) + } + } + else + { + /* PseudoColor/GrayScale - match on exact pixel */ + for (i = 0; i < ndef; i++) + { + if (pdef[i].pixel == + pPriv->colors[SOURCE_COLOR].pixel) + { + pPriv->colors[SOURCE_COLOR] = pdef[i]; + if (++updated == 2) + break; + } + if (pdef[i].pixel == + pPriv->colors[MASK_COLOR].pixel) + { + pPriv->colors[MASK_COLOR] = pdef[i]; + if (++updated == 2) + break; + } + } + } + if (updated) + { + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = MISPRITE(pDev); + pCursorInfo->checkPixels = TRUE; + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) + miSpriteRemoveCursor (pDev, pScreen); + } + } + } + } +} + +static void +miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) +{ + miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); + CursorPtr pCursor; + xColorItem *sourceColor, *maskColor; + + pCursor = pDevCursor->pCursor; + sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; + maskColor = &pScreenPriv->colors[MASK_COLOR]; + if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || + !(pCursor->foreRed == sourceColor->red && + pCursor->foreGreen == sourceColor->green && + pCursor->foreBlue == sourceColor->blue && + pCursor->backRed == maskColor->red && + pCursor->backGreen == maskColor->green && + pCursor->backBlue == maskColor->blue)) + { + pScreenPriv->pColormap = pScreenPriv->pInstalledMap; + sourceColor->red = pCursor->foreRed; + sourceColor->green = pCursor->foreGreen; + sourceColor->blue = pCursor->foreBlue; + FakeAllocColor (pScreenPriv->pColormap, sourceColor); + maskColor->red = pCursor->backRed; + maskColor->green = pCursor->backGreen; + maskColor->blue = pCursor->backBlue; + FakeAllocColor (pScreenPriv->pColormap, maskColor); + /* "free" the pixels right away, don't let this confuse you */ + FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); + FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); + } + + pDevCursor->checkPixels = FALSE; + +} + +/* + * miPointer interface routines + */ + +#define SPRITE_PAD 8 + +static Bool +miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + miCursorInfoPtr pCursorInfo; + + if (IsFloating(pDev)) + return FALSE; + + pCursorInfo = MISPRITE(pDev); + + if (pCursor == pCursorInfo->pCursor) + pCursorInfo->checkPixels = TRUE; + + return miDCRealizeCursor(pScreen, pCursor); +} + +static Bool +miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + return miDCUnrealizeCursor(pScreen, pCursor); +} + +static void +miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y) +{ + miCursorInfoPtr pPointer; + miSpriteScreenPtr pScreenPriv; + + if (IsFloating(pDev)) + return; + + pPointer = MISPRITE(pDev); + pScreenPriv = GetSpriteScreen(pScreen); + + if (!pCursor) + { + if (pPointer->shouldBeUp) + --pScreenPriv->numberOfCursors; + pPointer->shouldBeUp = FALSE; + if (pPointer->isUp) + miSpriteRemoveCursor (pDev, pScreen); + if (pScreenPriv->numberOfCursors == 0) + miSpriteDisableDamage(pScreen, pScreenPriv); + pPointer->pCursor = 0; + return; + } + if (!pPointer->shouldBeUp) + pScreenPriv->numberOfCursors++; + pPointer->shouldBeUp = TRUE; + if (!pPointer->isUp) + miSpriteRegisterBlockHandler(pScreen, pScreenPriv); + if (pPointer->x == x && + pPointer->y == y && + pPointer->pCursor == pCursor && + !pPointer->checkPixels) + { + return; + } + pPointer->x = x; + pPointer->y = y; + pPointer->pCacheWin = NullWindow; + if (pPointer->checkPixels || pPointer->pCursor != pCursor) + { + pPointer->pCursor = pCursor; + miSpriteFindColors (pPointer, pScreen); + } + if (pPointer->isUp) { + /* TODO: reimplement flicker-free MoveCursor */ + SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); + miSpriteRemoveCursor (pDev, pScreen); + } + + if (!pPointer->isUp && pPointer->pCursor) + { + SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); + miSpriteSaveUnderCursor(pDev, pScreen); + miSpriteRestoreCursor (pDev, pScreen); + } + +} + +static void +miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ + CursorPtr pCursor; + + if (IsFloating(pDev)) + return; + + pCursor = MISPRITE(pDev)->pCursor; + + miSpriteSetCursor (pDev, pScreen, pCursor, x, y); +} + + +static Bool +miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) +{ + int ret = miDCDeviceInitialize(pDev, pScreen); + + if (ret) + { + miCursorInfoPtr pCursorInfo; + pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + pCursorInfo->pCursor = NULL; + pCursorInfo->x = 0; + pCursorInfo->y = 0; + pCursorInfo->isUp = FALSE; + pCursorInfo->shouldBeUp = FALSE; + pCursorInfo->pCacheWin = NullWindow; + pCursorInfo->isInCacheWin = FALSE; + pCursorInfo->checkPixels = TRUE; + pCursorInfo->pScreen = FALSE; + } + + return ret; +} + +static void +miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) +{ + miCursorInfoPtr pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + + if (DevHasCursor(pDev)) + miDCDeviceCleanup(pDev, pScreen); + + memset(pCursorInfo, 0, sizeof(miCursorInfoRec)); +} + +/* + * undraw/draw cursor + */ + +static void +miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) +{ + miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; + + + if (IsFloating(pDev)) + return; + + DamageDrawInternal (pScreen, TRUE); + pScreenPriv = GetSpriteScreen(pScreen); + pCursorInfo = MISPRITE(pDev); + + miSpriteIsDown(pCursorInfo); + miSpriteRegisterBlockHandler(pScreen, pScreenPriv); + pCursorInfo->pCacheWin = NullWindow; + miSpriteDisableDamage(pScreen, pScreenPriv); + if (!miDCRestoreUnderCursor(pDev, + pScreen, + pCursorInfo->saved.x1, + pCursorInfo->saved.y1, + pCursorInfo->saved.x2 - + pCursorInfo->saved.x1, + pCursorInfo->saved.y2 - + pCursorInfo->saved.y1)) + { + miSpriteIsUp(pCursorInfo); + } + miSpriteEnableDamage(pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); +} + +/* + * Called from the block handler, saves area under cursor + * before waiting for something to do. + */ + +static void +miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) +{ + miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; + + if (IsFloating(pDev)) + return; + + DamageDrawInternal (pScreen, TRUE); + pScreenPriv = GetSpriteScreen(pScreen); + pCursorInfo = MISPRITE(pDev); + + miSpriteComputeSaved (pDev, pScreen); + + miSpriteDisableDamage(pScreen, pScreenPriv); + + miDCSaveUnderCursor(pDev, + pScreen, + pCursorInfo->saved.x1, + pCursorInfo->saved.y1, + pCursorInfo->saved.x2 - + pCursorInfo->saved.x1, + pCursorInfo->saved.y2 - + pCursorInfo->saved.y1); + SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); + miSpriteEnableDamage(pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); +} + + +/* + * Called from the block handler, restores the cursor + * before waiting for something to do. + */ + +static void +miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) +{ + miSpriteScreenPtr pScreenPriv; + int x, y; + CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; + + if (IsFloating(pDev)) + return; + + DamageDrawInternal (pScreen, TRUE); + pScreenPriv = GetSpriteScreen(pScreen); + pCursorInfo = MISPRITE(pDev); + + miSpriteComputeSaved (pDev, pScreen); + pCursor = pCursorInfo->pCursor; + + x = pCursorInfo->x - (int)pCursor->bits->xhot; + y = pCursorInfo->y - (int)pCursor->bits->yhot; + miSpriteDisableDamage(pScreen, pScreenPriv); + SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); + if (pCursorInfo->checkPixels) + miSpriteFindColors (pCursorInfo, pScreen); + if (miDCPutUpCursor(pDev, pScreen, + pCursor, x, y, + pScreenPriv->colors[SOURCE_COLOR].pixel, + pScreenPriv->colors[MASK_COLOR].pixel)) + { + miSpriteIsUp(pCursorInfo); + pCursorInfo->pScreen = pScreen; + } + miSpriteEnableDamage(pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); +} + +/* + * compute the desired area of the screen to save + */ + +static void +miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) +{ + int x, y, w, h; + int wpad, hpad; + CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; + + if (IsFloating(pDev)) + return; + + pCursorInfo = MISPRITE(pDev); + + pCursor = pCursorInfo->pCursor; + x = pCursorInfo->x - (int)pCursor->bits->xhot; + y = pCursorInfo->y - (int)pCursor->bits->yhot; + w = pCursor->bits->width; + h = pCursor->bits->height; + wpad = SPRITE_PAD; + hpad = SPRITE_PAD; + pCursorInfo->saved.x1 = x - wpad; + pCursorInfo->saved.y1 = y - hpad; + pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; + pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; +} + diff --git a/xorg-server/mi/mivaltree.c b/xorg-server/mi/mivaltree.c index 36ec8e60a..e1d47c06f 100644 --- a/xorg-server/mi/mivaltree.c +++ b/xorg-server/mi/mivaltree.c @@ -1,813 +1,811 @@ -/*
- * mivaltree.c --
- * Functions for recalculating window clip lists. Main function
- * is miValidateTree.
- *
-
-Copyright 1987, 1988, 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
- *
- * Copyright 1987, 1988, 1989 by
- * Digital Equipment Corporation, Maynard, Massachusetts,
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- ******************************************************************/
-
-/* The panoramix components contained the following notice */
-/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-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.
-
-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,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
-
-
- /*
- * Aug '86: Susan Angebranndt -- original code
- * July '87: Adam de Boor -- substantially modified and commented
- * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
- * In particular, much improved code for window mapping and
- * circulating.
- * Bob Scheifler -- avoid miComputeClips for unmapped windows,
- * valdata changes
- */
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "validate.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "regionstr.h"
-#include "mivalidate.h"
-
-#include "globals.h"
-
-/*
- * Compute the visibility of a shaped window
- */
-int
-miShapedWindowIn (RegionPtr universe, RegionPtr bounding,
- BoxPtr rect, int x, int y)
-{
- BoxRec box;
- BoxPtr boundBox;
- int nbox;
- Bool someIn, someOut;
- int t, x1, y1, x2, y2;
-
- nbox = RegionNumRects (bounding);
- boundBox = RegionRects (bounding);
- someIn = someOut = FALSE;
- x1 = rect->x1;
- y1 = rect->y1;
- x2 = rect->x2;
- y2 = rect->y2;
- while (nbox--)
- {
- if ((t = boundBox->x1 + x) < x1)
- t = x1;
- box.x1 = t;
- if ((t = boundBox->y1 + y) < y1)
- t = y1;
- box.y1 = t;
- if ((t = boundBox->x2 + x) > x2)
- t = x2;
- box.x2 = t;
- if ((t = boundBox->y2 + y) > y2)
- t = y2;
- box.y2 = t;
- if (box.x1 > box.x2)
- box.x2 = box.x1;
- if (box.y1 > box.y2)
- box.y2 = box.y1;
- switch (RegionContainsRect(universe, &box))
- {
- case rgnIN:
- if (someOut)
- return rgnPART;
- someIn = TRUE;
- break;
- case rgnOUT:
- if (someIn)
- return rgnPART;
- someOut = TRUE;
- break;
- default:
- return rgnPART;
- }
- boundBox++;
- }
- if (someIn)
- return rgnIN;
- return rgnOUT;
-}
-
-static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
-static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
-
-void
-miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
- GetRedirectBorderClipProcPtr getBorderClip)
-{
- miSetRedirectBorderClipProc = setBorderClip;
- miGetRedirectBorderClipProc = getBorderClip;
-}
-
-/*
- * Manual redirected windows are treated as transparent; they do not obscure
- * siblings or parent windows
- */
-
-#ifdef COMPOSITE
-#define TreatAsTransparent(w) ((w)->redirectDraw == RedirectDrawManual)
-#else
-#define TreatAsTransparent(w) FALSE
-#endif
-
-#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
- HasBorder(w) && \
- (w)->backgroundState == ParentRelative)
-
-
-/*
- *-----------------------------------------------------------------------
- * miComputeClips --
- * Recompute the clipList, borderClip, exposed and borderExposed
- * regions for pParent and its children. Only viewable windows are
- * taken into account.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * clipList, borderClip, exposed and borderExposed are altered.
- * A VisibilityNotify event may be generated on the parent window.
- *
- *-----------------------------------------------------------------------
- */
-static void
-miComputeClips (
- WindowPtr pParent,
- ScreenPtr pScreen,
- RegionPtr universe,
- VTKind kind,
- RegionPtr exposed ) /* for intermediate calculations */
-{
- int dx,
- dy;
- RegionRec childUniverse;
- WindowPtr pChild;
- int oldVis, newVis;
- BoxRec borderSize;
- RegionRec childUnion;
- Bool overlap;
- RegionPtr borderVisible;
- Bool resized;
- /*
- * Figure out the new visibility of this window.
- * The extent of the universe should be the same as the extent of
- * the borderSize region. If the window is unobscured, this rectangle
- * will be completely inside the universe (the universe will cover it
- * completely). If the window is completely obscured, none of the
- * universe will cover the rectangle.
- */
- borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
- borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
- dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
- if (dx > 32767)
- dx = 32767;
- borderSize.x2 = dx;
- dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
- if (dy > 32767)
- dy = 32767;
- borderSize.y2 = dy;
-
-#ifdef COMPOSITE
- /*
- * In redirected drawing case, reset universe to borderSize
- */
- if (pParent->redirectDraw != RedirectDrawNone)
- {
- if (miSetRedirectBorderClipProc)
- {
- if (TreatAsTransparent (pParent))
- RegionEmpty(universe);
- (*miSetRedirectBorderClipProc) (pParent, universe);
- }
- RegionCopy(universe, &pParent->borderSize);
- }
-#endif
-
- oldVis = pParent->visibility;
- switch (RegionContainsRect(universe, &borderSize))
- {
- case rgnIN:
- newVis = VisibilityUnobscured;
- break;
- case rgnPART:
- newVis = VisibilityPartiallyObscured;
- {
- RegionPtr pBounding;
-
- if ((pBounding = wBoundingShape (pParent)))
- {
- switch (miShapedWindowIn (universe, pBounding,
- &borderSize,
- pParent->drawable.x,
- pParent->drawable.y))
- {
- case rgnIN:
- newVis = VisibilityUnobscured;
- break;
- case rgnOUT:
- newVis = VisibilityFullyObscured;
- break;
- }
- }
- }
- break;
- default:
- newVis = VisibilityFullyObscured;
- break;
- }
- pParent->visibility = newVis;
- if (oldVis != newVis &&
- ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
- SendVisibilityNotify(pParent);
-
- dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
- dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
-
- /*
- * avoid computations when dealing with simple operations
- */
-
- switch (kind) {
- case VTMap:
- case VTStack:
- case VTUnmap:
- break;
- case VTMove:
- if ((oldVis == newVis) &&
- ((oldVis == VisibilityFullyObscured) ||
- (oldVis == VisibilityUnobscured)))
- {
- pChild = pParent;
- while (1)
- {
- if (pChild->viewable)
- {
- if (pChild->visibility != VisibilityFullyObscured)
- {
- RegionTranslate(&pChild->borderClip,
- dx, dy);
- RegionTranslate(&pChild->clipList,
- dx, dy);
- pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- if (pScreen->ClipNotify)
- (* pScreen->ClipNotify) (pChild, dx, dy);
-
- }
- if (pChild->valdata)
- {
- RegionNull(&pChild->valdata->after.borderExposed);
- if (HasParentRelativeBorder(pChild))
- {
- RegionSubtract(&pChild->valdata->after.borderExposed,
- &pChild->borderClip,
- &pChild->winSize);
- }
- RegionNull(&pChild->valdata->after.exposed);
- }
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pParent))
- pChild = pChild->parent;
- if (pChild == pParent)
- break;
- pChild = pChild->nextSib;
- }
- return;
- }
- /* fall through */
- default:
- /*
- * To calculate exposures correctly, we have to translate the old
- * borderClip and clipList regions to the window's new location so there
- * is a correspondence between pieces of the new and old clipping regions.
- */
- if (dx || dy)
- {
- /*
- * We translate the old clipList because that will be exposed or copied
- * if gravity is right.
- */
- RegionTranslate(&pParent->borderClip, dx, dy);
- RegionTranslate(&pParent->clipList, dx, dy);
- }
- break;
- case VTBroken:
- RegionEmpty(&pParent->borderClip);
- RegionEmpty(&pParent->clipList);
- break;
- }
-
- borderVisible = pParent->valdata->before.borderVisible;
- resized = pParent->valdata->before.resized;
- RegionNull(&pParent->valdata->after.borderExposed);
- RegionNull(&pParent->valdata->after.exposed);
-
- /*
- * Since the borderClip must not be clipped by the children, we do
- * the border exposure first...
- *
- * 'universe' is the window's borderClip. To figure the exposures, remove
- * the area that used to be exposed from the new.
- * This leaves a region of pieces that weren't exposed before.
- */
-
- if (HasBorder (pParent))
- {
- if (borderVisible)
- {
- /*
- * when the border changes shape, the old visible portions
- * of the border will be saved by DIX in borderVisible --
- * use that region and destroy it
- */
- RegionSubtract(exposed, universe, borderVisible);
- RegionDestroy(borderVisible);
- }
- else
- {
- RegionSubtract(exposed, universe, &pParent->borderClip);
- }
- if (HasParentRelativeBorder(pParent) && (dx || dy))
- RegionSubtract(&pParent->valdata->after.borderExposed,
- universe,
- &pParent->winSize);
- else
- RegionSubtract(&pParent->valdata->after.borderExposed,
- exposed, &pParent->winSize);
-
- RegionCopy(&pParent->borderClip, universe);
-
- /*
- * To get the right clipList for the parent, and to make doubly sure
- * that no child overlaps the parent's border, we remove the parent's
- * border from the universe before proceeding.
- */
-
- RegionIntersect(universe, universe, &pParent->winSize);
- }
- else
- RegionCopy(&pParent->borderClip, universe);
-
- if ((pChild = pParent->firstChild) && pParent->mapped)
- {
- RegionNull(&childUniverse);
- RegionNull(&childUnion);
- if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
- ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
- (pChild->drawable.x < pParent->lastChild->drawable.x)))
- {
- for (; pChild; pChild = pChild->nextSib)
- {
- if (pChild->viewable && !TreatAsTransparent(pChild))
- RegionAppend(&childUnion, &pChild->borderSize);
- }
- }
- else
- {
- for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
- {
- if (pChild->viewable && !TreatAsTransparent(pChild))
- RegionAppend(&childUnion, &pChild->borderSize);
- }
- }
- RegionValidate(&childUnion, &overlap);
-
- for (pChild = pParent->firstChild;
- pChild;
- pChild = pChild->nextSib)
- {
- if (pChild->viewable) {
- /*
- * If the child is viewable, we want to remove its extents
- * from the current universe, but we only re-clip it if
- * it's been marked.
- */
- if (pChild->valdata) {
- /*
- * Figure out the new universe from the child's
- * perspective and recurse.
- */
- RegionIntersect(&childUniverse,
- universe,
- &pChild->borderSize);
- miComputeClips (pChild, pScreen, &childUniverse, kind,
- exposed);
- }
- /*
- * Once the child has been processed, we remove its extents
- * from the current universe, thus denying its space to any
- * other sibling.
- */
- if (overlap && !TreatAsTransparent (pChild))
- RegionSubtract(universe, universe,
- &pChild->borderSize);
- }
- }
- if (!overlap)
- RegionSubtract(universe, universe, &childUnion);
- RegionUninit(&childUnion);
- RegionUninit(&childUniverse);
- } /* if any children */
-
- /*
- * 'universe' now contains the new clipList for the parent window.
- *
- * To figure the exposure of the window we subtract the old clip from the
- * new, just as for the border.
- */
-
- if (oldVis == VisibilityFullyObscured ||
- oldVis == VisibilityNotViewable)
- {
- RegionCopy(&pParent->valdata->after.exposed, universe);
- }
- else if (newVis != VisibilityFullyObscured &&
- newVis != VisibilityNotViewable)
- {
- RegionSubtract(&pParent->valdata->after.exposed,
- universe, &pParent->clipList);
- }
-
- /* HACK ALERT - copying contents of regions, instead of regions */
- {
- RegionRec tmp;
-
- tmp = pParent->clipList;
- pParent->clipList = *universe;
- *universe = tmp;
- }
-
-#ifdef NOTDEF
- RegionCopy(&pParent->clipList, universe);
-#endif
-
- pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- if (pScreen->ClipNotify)
- (* pScreen->ClipNotify) (pParent, dx, dy);
-}
-
-static void
-miTreeObscured(
- WindowPtr pParent )
-{
- WindowPtr pChild;
- int oldVis;
-
- pChild = pParent;
- while (1)
- {
- if (pChild->viewable)
- {
- oldVis = pChild->visibility;
- if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
- ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
- SendVisibilityNotify(pChild);
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pParent))
- pChild = pChild->parent;
- if (pChild == pParent)
- break;
- pChild = pChild->nextSib;
- }
-}
-
-/*
- *-----------------------------------------------------------------------
- * miValidateTree --
- * Recomputes the clip list for pParent and all its inferiors.
- *
- * Results:
- * Always returns 1.
- *
- * Side Effects:
- * The clipList, borderClip, exposed, and borderExposed regions for
- * each marked window are altered.
- *
- * Notes:
- * This routine assumes that all affected windows have been marked
- * (valdata created) and their winSize and borderSize regions
- * adjusted to correspond to their new positions. The borderClip and
- * clipList regions should not have been touched.
- *
- * The top-most level is treated differently from all lower levels
- * because pParent is unchanged. For the top level, we merge the
- * regions taken up by the marked children back into the clipList
- * for pParent, thus forming a region from which the marked children
- * can claim their areas. For lower levels, where the old clipList
- * and borderClip are invalid, we can't do this and have to do the
- * extra operations done in miComputeClips, but this is much faster
- * e.g. when only one child has moved...
- *
- *-----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-int
-miValidateTree (
- WindowPtr pParent, /* Parent to validate */
- WindowPtr pChild, /* First child of pParent that was
- * affected */
- VTKind kind /* What kind of configuration caused call */
- )
-{
- RegionRec totalClip; /* Total clipping region available to
- * the marked children. pParent's clipList
- * merged with the borderClips of all
- * the marked children. */
- RegionRec childClip; /* The new borderClip for the current
- * child */
- RegionRec childUnion; /* the space covered by borderSize for
- * all marked children */
- RegionRec exposed; /* For intermediate calculations */
- ScreenPtr pScreen;
- WindowPtr pWin;
- Bool overlap;
- int viewvals;
- Bool forward;
-
- pScreen = pParent->drawable.pScreen;
- if (pChild == NullWindow)
- pChild = pParent->firstChild;
-
- RegionNull(&childClip);
- RegionNull(&exposed);
-
- /*
- * compute the area of the parent window occupied
- * by the marked children + the parent itself. This
- * is the area which can be divied up among the marked
- * children in their new configuration.
- */
- RegionNull(&totalClip);
- viewvals = 0;
- if (RegionBroken(&pParent->clipList) &&
- !RegionBroken(&pParent->borderClip))
- {
- kind = VTBroken;
- /*
- * When rebuilding clip lists after out of memory,
- * assume everything is busted.
- */
- forward = TRUE;
- RegionCopy(&totalClip, &pParent->borderClip);
- RegionIntersect(&totalClip, &totalClip, &pParent->winSize);
-
- for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
- {
- if (pWin->viewable && !TreatAsTransparent (pWin))
- RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
- }
- for (pWin = pChild; pWin; pWin = pWin->nextSib)
- if (pWin->valdata && pWin->viewable)
- viewvals++;
-
- RegionEmpty(&pParent->clipList);
- }
- else
- {
- if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
- ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
- (pChild->drawable.x < pParent->lastChild->drawable.x)))
- {
- forward = TRUE;
- for (pWin = pChild; pWin; pWin = pWin->nextSib)
- {
- if (pWin->valdata)
- {
- RegionPtr pBorderClip = &pWin->borderClip;
-#ifdef COMPOSITE
- if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
- pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
-#endif
- RegionAppend(&totalClip, pBorderClip );
- if (pWin->viewable)
- viewvals++;
- }
- }
- }
- else
- {
- forward = FALSE;
- pWin = pParent->lastChild;
- while (1)
- {
- if (pWin->valdata)
- {
- RegionPtr pBorderClip = &pWin->borderClip;
-#ifdef COMPOSITE
- if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
- pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
-#endif
- RegionAppend(&totalClip, pBorderClip );
- if (pWin->viewable)
- viewvals++;
- }
- if (pWin == pChild)
- break;
- pWin = pWin->prevSib;
- }
- }
- RegionValidate(&totalClip, &overlap);
- }
-
- /*
- * Now go through the children of the root and figure their new
- * borderClips from the totalClip, passing that off to miComputeClips
- * to handle recursively. Once that's done, we remove the child
- * from the totalClip to clip any siblings below it.
- */
-
- overlap = TRUE;
- if (kind != VTStack)
- {
- RegionUnion(&totalClip, &totalClip, &pParent->clipList);
- if (viewvals > 1)
- {
- /*
- * precompute childUnion to discover whether any of them
- * overlap. This seems redundant, but performance studies
- * have demonstrated that the cost of this loop is
- * lower than the cost of multiple Subtracts in the
- * loop below.
- */
- RegionNull(&childUnion);
- if (forward)
- {
- for (pWin = pChild; pWin; pWin = pWin->nextSib)
- if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
- RegionAppend(&childUnion,
- &pWin->borderSize);
- }
- else
- {
- pWin = pParent->lastChild;
- while (1)
- {
- if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
- RegionAppend(&childUnion,
- &pWin->borderSize);
- if (pWin == pChild)
- break;
- pWin = pWin->prevSib;
- }
- }
- RegionValidate(&childUnion, &overlap);
- if (overlap)
- RegionUninit(&childUnion);
- }
- }
-
- for (pWin = pChild;
- pWin != NullWindow;
- pWin = pWin->nextSib)
- {
- if (pWin->viewable) {
- if (pWin->valdata) {
- RegionIntersect(&childClip,
- &totalClip,
- &pWin->borderSize);
- miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
- if (overlap && !TreatAsTransparent (pWin))
- {
- RegionSubtract(&totalClip,
- &totalClip,
- &pWin->borderSize);
- }
- } else if (pWin->visibility == VisibilityNotViewable) {
- miTreeObscured(pWin);
- }
- } else {
- if (pWin->valdata) {
- RegionEmpty(&pWin->clipList);
- if (pScreen->ClipNotify)
- (* pScreen->ClipNotify) (pWin, 0, 0);
- RegionEmpty(&pWin->borderClip);
- pWin->valdata = NULL;
- }
- }
- }
-
- RegionUninit(&childClip);
- if (!overlap)
- {
- RegionSubtract(&totalClip, &totalClip, &childUnion);
- RegionUninit(&childUnion);
- }
-
- RegionNull(&pParent->valdata->after.exposed);
- RegionNull(&pParent->valdata->after.borderExposed);
-
- /*
- * each case below is responsible for updating the
- * clipList and serial number for the parent window
- */
-
- switch (kind) {
- case VTStack:
- break;
- default:
- /*
- * totalClip contains the new clipList for the parent. Figure out
- * exposures and obscures as per miComputeClips and reset the parent's
- * clipList.
- */
- RegionSubtract(&pParent->valdata->after.exposed,
- &totalClip, &pParent->clipList);
- /* fall through */
- case VTMap:
- RegionCopy(&pParent->clipList, &totalClip);
- pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- break;
- }
-
- RegionUninit(&totalClip);
- RegionUninit(&exposed);
- if (pScreen->ClipNotify)
- (*pScreen->ClipNotify) (pParent, 0, 0);
- return 1;
-}
+/* + * mivaltree.c -- + * Functions for recalculating window clip lists. Main function + * is miValidateTree. + * + +Copyright 1987, 1988, 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * + * Copyright 1987, 1988, 1989 by + * Digital Equipment Corporation, Maynard, Massachusetts, + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + ******************************************************************/ + +/* The panoramix components contained the following notice */ +/***************************************************************** + +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. + +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. + +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, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. + +******************************************************************/ + + + /* + * Aug '86: Susan Angebranndt -- original code + * July '87: Adam de Boor -- substantially modified and commented + * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible. + * In particular, much improved code for window mapping and + * circulating. + * Bob Scheifler -- avoid miComputeClips for unmapped windows, + * valdata changes + */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "scrnintstr.h" +#include "validate.h" +#include "windowstr.h" +#include "mi.h" +#include "regionstr.h" +#include "mivalidate.h" + +#include "globals.h" + +/* + * Compute the visibility of a shaped window + */ +int +miShapedWindowIn (RegionPtr universe, RegionPtr bounding, + BoxPtr rect, int x, int y) +{ + BoxRec box; + BoxPtr boundBox; + int nbox; + Bool someIn, someOut; + int t, x1, y1, x2, y2; + + nbox = RegionNumRects (bounding); + boundBox = RegionRects (bounding); + someIn = someOut = FALSE; + x1 = rect->x1; + y1 = rect->y1; + x2 = rect->x2; + y2 = rect->y2; + while (nbox--) + { + if ((t = boundBox->x1 + x) < x1) + t = x1; + box.x1 = t; + if ((t = boundBox->y1 + y) < y1) + t = y1; + box.y1 = t; + if ((t = boundBox->x2 + x) > x2) + t = x2; + box.x2 = t; + if ((t = boundBox->y2 + y) > y2) + t = y2; + box.y2 = t; + if (box.x1 > box.x2) + box.x2 = box.x1; + if (box.y1 > box.y2) + box.y2 = box.y1; + switch (RegionContainsRect(universe, &box)) + { + case rgnIN: + if (someOut) + return rgnPART; + someIn = TRUE; + break; + case rgnOUT: + if (someIn) + return rgnPART; + someOut = TRUE; + break; + default: + return rgnPART; + } + boundBox++; + } + if (someIn) + return rgnIN; + return rgnOUT; +} + +static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc; +static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc; + +void +miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, + GetRedirectBorderClipProcPtr getBorderClip) +{ + miSetRedirectBorderClipProc = setBorderClip; + miGetRedirectBorderClipProc = getBorderClip; +} + +/* + * Manual redirected windows are treated as transparent; they do not obscure + * siblings or parent windows + */ + +#ifdef COMPOSITE +#define TreatAsTransparent(w) ((w)->redirectDraw == RedirectDrawManual) +#else +#define TreatAsTransparent(w) FALSE +#endif + +#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ + HasBorder(w) && \ + (w)->backgroundState == ParentRelative) + + +/* + *----------------------------------------------------------------------- + * miComputeClips -- + * Recompute the clipList, borderClip, exposed and borderExposed + * regions for pParent and its children. Only viewable windows are + * taken into account. + * + * Results: + * None. + * + * Side Effects: + * clipList, borderClip, exposed and borderExposed are altered. + * A VisibilityNotify event may be generated on the parent window. + * + *----------------------------------------------------------------------- + */ +static void +miComputeClips ( + WindowPtr pParent, + ScreenPtr pScreen, + RegionPtr universe, + VTKind kind, + RegionPtr exposed ) /* for intermediate calculations */ +{ + int dx, + dy; + RegionRec childUniverse; + WindowPtr pChild; + int oldVis, newVis; + BoxRec borderSize; + RegionRec childUnion; + Bool overlap; + RegionPtr borderVisible; + /* + * Figure out the new visibility of this window. + * The extent of the universe should be the same as the extent of + * the borderSize region. If the window is unobscured, this rectangle + * will be completely inside the universe (the universe will cover it + * completely). If the window is completely obscured, none of the + * universe will cover the rectangle. + */ + borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); + borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); + dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); + if (dx > 32767) + dx = 32767; + borderSize.x2 = dx; + dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); + if (dy > 32767) + dy = 32767; + borderSize.y2 = dy; + +#ifdef COMPOSITE + /* + * In redirected drawing case, reset universe to borderSize + */ + if (pParent->redirectDraw != RedirectDrawNone) + { + if (miSetRedirectBorderClipProc) + { + if (TreatAsTransparent (pParent)) + RegionEmpty(universe); + (*miSetRedirectBorderClipProc) (pParent, universe); + } + RegionCopy(universe, &pParent->borderSize); + } +#endif + + oldVis = pParent->visibility; + switch (RegionContainsRect(universe, &borderSize)) + { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnPART: + newVis = VisibilityPartiallyObscured; + { + RegionPtr pBounding; + + if ((pBounding = wBoundingShape (pParent))) + { + switch (miShapedWindowIn (universe, pBounding, + &borderSize, + pParent->drawable.x, + pParent->drawable.y)) + { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnOUT: + newVis = VisibilityFullyObscured; + break; + } + } + } + break; + default: + newVis = VisibilityFullyObscured; + break; + } + pParent->visibility = newVis; + if (oldVis != newVis && + ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) + SendVisibilityNotify(pParent); + + dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; + dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; + + /* + * avoid computations when dealing with simple operations + */ + + switch (kind) { + case VTMap: + case VTStack: + case VTUnmap: + break; + case VTMove: + if ((oldVis == newVis) && + ((oldVis == VisibilityFullyObscured) || + (oldVis == VisibilityUnobscured))) + { + pChild = pParent; + while (1) + { + if (pChild->viewable) + { + if (pChild->visibility != VisibilityFullyObscured) + { + RegionTranslate(&pChild->borderClip, + dx, dy); + RegionTranslate(&pChild->clipList, + dx, dy); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + if (pScreen->ClipNotify) + (* pScreen->ClipNotify) (pChild, dx, dy); + + } + if (pChild->valdata) + { + RegionNull(&pChild->valdata->after.borderExposed); + if (HasParentRelativeBorder(pChild)) + { + RegionSubtract(&pChild->valdata->after.borderExposed, + &pChild->borderClip, + &pChild->winSize); + } + RegionNull(&pChild->valdata->after.exposed); + } + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; + } + return; + } + /* fall through */ + default: + /* + * To calculate exposures correctly, we have to translate the old + * borderClip and clipList regions to the window's new location so there + * is a correspondence between pieces of the new and old clipping regions. + */ + if (dx || dy) + { + /* + * We translate the old clipList because that will be exposed or copied + * if gravity is right. + */ + RegionTranslate(&pParent->borderClip, dx, dy); + RegionTranslate(&pParent->clipList, dx, dy); + } + break; + case VTBroken: + RegionEmpty(&pParent->borderClip); + RegionEmpty(&pParent->clipList); + break; + } + + borderVisible = pParent->valdata->before.borderVisible; + RegionNull(&pParent->valdata->after.borderExposed); + RegionNull(&pParent->valdata->after.exposed); + + /* + * Since the borderClip must not be clipped by the children, we do + * the border exposure first... + * + * 'universe' is the window's borderClip. To figure the exposures, remove + * the area that used to be exposed from the new. + * This leaves a region of pieces that weren't exposed before. + */ + + if (HasBorder (pParent)) + { + if (borderVisible) + { + /* + * when the border changes shape, the old visible portions + * of the border will be saved by DIX in borderVisible -- + * use that region and destroy it + */ + RegionSubtract(exposed, universe, borderVisible); + RegionDestroy(borderVisible); + } + else + { + RegionSubtract(exposed, universe, &pParent->borderClip); + } + if (HasParentRelativeBorder(pParent) && (dx || dy)) + RegionSubtract(&pParent->valdata->after.borderExposed, + universe, + &pParent->winSize); + else + RegionSubtract(&pParent->valdata->after.borderExposed, + exposed, &pParent->winSize); + + RegionCopy(&pParent->borderClip, universe); + + /* + * To get the right clipList for the parent, and to make doubly sure + * that no child overlaps the parent's border, we remove the parent's + * border from the universe before proceeding. + */ + + RegionIntersect(universe, universe, &pParent->winSize); + } + else + RegionCopy(&pParent->borderClip, universe); + + if ((pChild = pParent->firstChild) && pParent->mapped) + { + RegionNull(&childUniverse); + RegionNull(&childUnion); + if ((pChild->drawable.y < pParent->lastChild->drawable.y) || + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) + { + for (; pChild; pChild = pChild->nextSib) + { + if (pChild->viewable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + else + { + for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) + { + if (pChild->viewable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + RegionValidate(&childUnion, &overlap); + + for (pChild = pParent->firstChild; + pChild; + pChild = pChild->nextSib) + { + if (pChild->viewable) { + /* + * If the child is viewable, we want to remove its extents + * from the current universe, but we only re-clip it if + * it's been marked. + */ + if (pChild->valdata) { + /* + * Figure out the new universe from the child's + * perspective and recurse. + */ + RegionIntersect(&childUniverse, + universe, + &pChild->borderSize); + miComputeClips (pChild, pScreen, &childUniverse, kind, + exposed); + } + /* + * Once the child has been processed, we remove its extents + * from the current universe, thus denying its space to any + * other sibling. + */ + if (overlap && !TreatAsTransparent (pChild)) + RegionSubtract(universe, universe, + &pChild->borderSize); + } + } + if (!overlap) + RegionSubtract(universe, universe, &childUnion); + RegionUninit(&childUnion); + RegionUninit(&childUniverse); + } /* if any children */ + + /* + * 'universe' now contains the new clipList for the parent window. + * + * To figure the exposure of the window we subtract the old clip from the + * new, just as for the border. + */ + + if (oldVis == VisibilityFullyObscured || + oldVis == VisibilityNotViewable) + { + RegionCopy(&pParent->valdata->after.exposed, universe); + } + else if (newVis != VisibilityFullyObscured && + newVis != VisibilityNotViewable) + { + RegionSubtract(&pParent->valdata->after.exposed, + universe, &pParent->clipList); + } + + /* HACK ALERT - copying contents of regions, instead of regions */ + { + RegionRec tmp; + + tmp = pParent->clipList; + pParent->clipList = *universe; + *universe = tmp; + } + +#ifdef NOTDEF + RegionCopy(&pParent->clipList, universe); +#endif + + pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + if (pScreen->ClipNotify) + (* pScreen->ClipNotify) (pParent, dx, dy); +} + +static void +miTreeObscured( + WindowPtr pParent ) +{ + WindowPtr pChild; + int oldVis; + + pChild = pParent; + while (1) + { + if (pChild->viewable) + { + oldVis = pChild->visibility; + if (oldVis != (pChild->visibility = VisibilityFullyObscured) && + ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) + SendVisibilityNotify(pChild); + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; + } +} + +/* + *----------------------------------------------------------------------- + * miValidateTree -- + * Recomputes the clip list for pParent and all its inferiors. + * + * Results: + * Always returns 1. + * + * Side Effects: + * The clipList, borderClip, exposed, and borderExposed regions for + * each marked window are altered. + * + * Notes: + * This routine assumes that all affected windows have been marked + * (valdata created) and their winSize and borderSize regions + * adjusted to correspond to their new positions. The borderClip and + * clipList regions should not have been touched. + * + * The top-most level is treated differently from all lower levels + * because pParent is unchanged. For the top level, we merge the + * regions taken up by the marked children back into the clipList + * for pParent, thus forming a region from which the marked children + * can claim their areas. For lower levels, where the old clipList + * and borderClip are invalid, we can't do this and have to do the + * extra operations done in miComputeClips, but this is much faster + * e.g. when only one child has moved... + * + *----------------------------------------------------------------------- + */ +/*ARGSUSED*/ +int +miValidateTree ( + WindowPtr pParent, /* Parent to validate */ + WindowPtr pChild, /* First child of pParent that was + * affected */ + VTKind kind /* What kind of configuration caused call */ + ) +{ + RegionRec totalClip; /* Total clipping region available to + * the marked children. pParent's clipList + * merged with the borderClips of all + * the marked children. */ + RegionRec childClip; /* The new borderClip for the current + * child */ + RegionRec childUnion; /* the space covered by borderSize for + * all marked children */ + RegionRec exposed; /* For intermediate calculations */ + ScreenPtr pScreen; + WindowPtr pWin; + Bool overlap; + int viewvals; + Bool forward; + + pScreen = pParent->drawable.pScreen; + if (pChild == NullWindow) + pChild = pParent->firstChild; + + RegionNull(&childClip); + RegionNull(&exposed); + + /* + * compute the area of the parent window occupied + * by the marked children + the parent itself. This + * is the area which can be divied up among the marked + * children in their new configuration. + */ + RegionNull(&totalClip); + viewvals = 0; + if (RegionBroken(&pParent->clipList) && + !RegionBroken(&pParent->borderClip)) + { + kind = VTBroken; + /* + * When rebuilding clip lists after out of memory, + * assume everything is busted. + */ + forward = TRUE; + RegionCopy(&totalClip, &pParent->borderClip); + RegionIntersect(&totalClip, &totalClip, &pParent->winSize); + + for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) + { + if (pWin->viewable && !TreatAsTransparent (pWin)) + RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); + } + for (pWin = pChild; pWin; pWin = pWin->nextSib) + if (pWin->valdata && pWin->viewable) + viewvals++; + + RegionEmpty(&pParent->clipList); + } + else + { + if ((pChild->drawable.y < pParent->lastChild->drawable.y) || + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) + { + forward = TRUE; + for (pWin = pChild; pWin; pWin = pWin->nextSib) + { + if (pWin->valdata) + { + RegionPtr pBorderClip = &pWin->borderClip; +#ifdef COMPOSITE + if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) + pBorderClip = (*miGetRedirectBorderClipProc)(pWin); +#endif + RegionAppend(&totalClip, pBorderClip ); + if (pWin->viewable) + viewvals++; + } + } + } + else + { + forward = FALSE; + pWin = pParent->lastChild; + while (1) + { + if (pWin->valdata) + { + RegionPtr pBorderClip = &pWin->borderClip; +#ifdef COMPOSITE + if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) + pBorderClip = (*miGetRedirectBorderClipProc)(pWin); +#endif + RegionAppend(&totalClip, pBorderClip ); + if (pWin->viewable) + viewvals++; + } + if (pWin == pChild) + break; + pWin = pWin->prevSib; + } + } + RegionValidate(&totalClip, &overlap); + } + + /* + * Now go through the children of the root and figure their new + * borderClips from the totalClip, passing that off to miComputeClips + * to handle recursively. Once that's done, we remove the child + * from the totalClip to clip any siblings below it. + */ + + overlap = TRUE; + if (kind != VTStack) + { + RegionUnion(&totalClip, &totalClip, &pParent->clipList); + if (viewvals > 1) + { + /* + * precompute childUnion to discover whether any of them + * overlap. This seems redundant, but performance studies + * have demonstrated that the cost of this loop is + * lower than the cost of multiple Subtracts in the + * loop below. + */ + RegionNull(&childUnion); + if (forward) + { + for (pWin = pChild; pWin; pWin = pWin->nextSib) + if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) + RegionAppend(&childUnion, + &pWin->borderSize); + } + else + { + pWin = pParent->lastChild; + while (1) + { + if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) + RegionAppend(&childUnion, + &pWin->borderSize); + if (pWin == pChild) + break; + pWin = pWin->prevSib; + } + } + RegionValidate(&childUnion, &overlap); + if (overlap) + RegionUninit(&childUnion); + } + } + + for (pWin = pChild; + pWin != NullWindow; + pWin = pWin->nextSib) + { + if (pWin->viewable) { + if (pWin->valdata) { + RegionIntersect(&childClip, + &totalClip, + &pWin->borderSize); + miComputeClips (pWin, pScreen, &childClip, kind, &exposed); + if (overlap && !TreatAsTransparent (pWin)) + { + RegionSubtract(&totalClip, + &totalClip, + &pWin->borderSize); + } + } else if (pWin->visibility == VisibilityNotViewable) { + miTreeObscured(pWin); + } + } else { + if (pWin->valdata) { + RegionEmpty(&pWin->clipList); + if (pScreen->ClipNotify) + (* pScreen->ClipNotify) (pWin, 0, 0); + RegionEmpty(&pWin->borderClip); + pWin->valdata = NULL; + } + } + } + + RegionUninit(&childClip); + if (!overlap) + { + RegionSubtract(&totalClip, &totalClip, &childUnion); + RegionUninit(&childUnion); + } + + RegionNull(&pParent->valdata->after.exposed); + RegionNull(&pParent->valdata->after.borderExposed); + + /* + * each case below is responsible for updating the + * clipList and serial number for the parent window + */ + + switch (kind) { + case VTStack: + break; + default: + /* + * totalClip contains the new clipList for the parent. Figure out + * exposures and obscures as per miComputeClips and reset the parent's + * clipList. + */ + RegionSubtract(&pParent->valdata->after.exposed, + &totalClip, &pParent->clipList); + /* fall through */ + case VTMap: + RegionCopy(&pParent->clipList, &totalClip); + pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; + break; + } + + RegionUninit(&totalClip); + RegionUninit(&exposed); + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pParent, 0, 0); + return 1; +} diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c index f51976284..2eddf066a 100644 --- a/xorg-server/os/log.c +++ b/xorg-server/os/log.c @@ -165,6 +165,9 @@ asm (".desc ___crashreporter_info__, 0x10"); #ifndef X_NOT_IMPLEMENTED_STRING #define X_NOT_IMPLEMENTED_STRING "(NI)" #endif +#ifndef X_NONE_STRING +#define X_NONE_STRING "" +#endif /* * LogInit is called to start logging to a file. It is also called (with @@ -325,58 +328,65 @@ LogWrite(int verb, const char *f, ...) va_end(args); } +/* Returns the Message Type string to prepend to a logging message, or NULL + * if the message will be dropped due to insufficient verbosity. */ +static const char * +LogMessageTypeVerbString(MessageType type, int verb) +{ + if (type == X_ERROR) + verb = 0; + + if (logVerbosity < verb && logFileVerbosity < verb) + return NULL; + + switch (type) { + case X_PROBED: + return X_PROBE_STRING; + case X_CONFIG: + return X_CONFIG_STRING; + case X_DEFAULT: + return X_DEFAULT_STRING; + case X_CMDLINE: + return X_CMDLINE_STRING; + case X_NOTICE: + return X_NOTICE_STRING; + case X_ERROR: + return X_ERROR_STRING; + case X_WARNING: + return X_WARNING_STRING; + case X_INFO: + return X_INFO_STRING; + case X_NOT_IMPLEMENTED: + return X_NOT_IMPLEMENTED_STRING; + case X_UNKNOWN: + return X_UNKNOWN_STRING; + case X_NONE: + return X_NONE_STRING; + default: + return X_UNKNOWN_STRING; + } +} + void LogVMessageVerb(MessageType type, int verb, const char *format, va_list args) { - const char *s = X_UNKNOWN_STRING; - char tmpBuf[1024]; - - /* Ignore verbosity for X_ERROR */ - if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) { - switch (type) { - case X_PROBED: - s = X_PROBE_STRING; - break; - case X_CONFIG: - s = X_CONFIG_STRING; - break; - case X_DEFAULT: - s = X_DEFAULT_STRING; - break; - case X_CMDLINE: - s = X_CMDLINE_STRING; - break; - case X_NOTICE: - s = X_NOTICE_STRING; - break; - case X_ERROR: - s = X_ERROR_STRING; - if (verb > 0) - verb = 0; - break; - case X_WARNING: - s = X_WARNING_STRING; - break; - case X_INFO: - s = X_INFO_STRING; - break; - case X_NOT_IMPLEMENTED: - s = X_NOT_IMPLEMENTED_STRING; - break; - case X_UNKNOWN: - s = X_UNKNOWN_STRING; - break; - case X_NONE: - s = NULL; - break; - } - - /* if s is not NULL we need a space before format */ - snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "", - s ? " " : "", - format); - LogVWrite(verb, tmpBuf, args); + const char *type_str; + char tmpFormat[1024]; + char *new_format; + + type_str = LogMessageTypeVerbString(type, verb); + if (!type_str) + return; + + /* if type_str is not "", prepend it and ' ', to format */ + if (type_str[0] == '\0') + new_format = format; + else { + new_format = tmpFormat; + snprintf(tmpFormat, sizeof(tmpFormat), "%s %s", type_str, format); } + + LogVWrite(verb, new_format, args); } /* Log message with verbosity level specified. */ @@ -401,6 +411,61 @@ LogMessage(MessageType type, const char *format, ...) va_end(ap); } + +void +LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format, + va_list msg_args, const char *hdr_format, va_list hdr_args) +{ + const char *type_str; + char tmpFormat[1024]; + char *tmpFormat_end = &tmpFormat[sizeof(tmpFormat)]; + char *p; + int left; + + type_str = LogMessageTypeVerbString(type, verb); + if (!type_str) + return; + + /* if type_str != "", copy it and ' ' to tmpFormat; set p after ' ' */ + p = tmpFormat; + if (type_str[0] != '\0') + p += snprintf(tmpFormat, sizeof(tmpFormat), "%s ", type_str); + + /* append as much of hdr as fits after type_str (if there was one) */ + left = tmpFormat_end - p; + if (left > 1) + p += vsnprintf(p, left, hdr_format, hdr_args); + + /* append as much of msg_format as will fit after hdr */ + left = tmpFormat_end - p; + if (left > 1) + snprintf(p, left, "%s", msg_format); + + LogVWrite(verb, tmpFormat, msg_args); +} + +void +LogHdrMessageVerb(MessageType type, int verb, const char *msg_format, + va_list msg_args, const char *hdr_format, ...) +{ + va_list hdr_args; + + va_start(hdr_args, hdr_format); + LogVHdrMessageVerb(type, verb, msg_format, msg_args, hdr_format, hdr_args); + va_end(hdr_args); +} + +void +LogHdrMessage(MessageType type, const char *msg_format, va_list msg_args, + const char *hdr_format, ...) +{ + va_list hdr_args; + + va_start(hdr_args, hdr_format); + LogVHdrMessageVerb(type, 1, msg_format, msg_args, hdr_format, hdr_args); + va_end(hdr_args); +} + void AbortServer(void) _X_NORETURN; diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c index 36cb46f11..e8ecb7193 100644 --- a/xorg-server/os/utils.c +++ b/xorg-server/os/utils.c @@ -201,6 +201,8 @@ Bool PanoramiXExtensionDisabledHack = FALSE; int auditTrailLevel = 1; +char *SeatId = NULL; + #if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED) #define HAS_SAVED_IDS_AND_SETEUID #endif @@ -511,6 +513,7 @@ void UseMsg(void) ErrorF("-render [default|mono|gray|color] set render color alloc policy\n"); ErrorF("-retro start with classic stipple and cursor\n"); ErrorF("-s # screen-saver timeout (minutes)\n"); + ErrorF("-seat string seat to run on\n"); ErrorF("-t # default pointer threshold (pixels/t)\n"); ErrorF("-terminate terminate at server reset\n"); ErrorF("-to # connection time out\n"); @@ -802,6 +805,13 @@ ProcessCommandLine(int argc, char *argv[]) else UseMsg(); } + else if ( strcmp( argv[i], "-seat") == 0) + { + if(++i < argc) + SeatId = argv[i]; + else + UseMsg(); + } else if ( strcmp( argv[i], "-t") == 0) { if(++i < argc) diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index 7ef408c93..689dd7f60 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -1,7 +1,7 @@ if ENABLE_UNIT_TESTS if HAVE_LD_WRAP SUBDIRS= . xi2 -noinst_PROGRAMS = xkb input xtest list misc fixes +noinst_PROGRAMS = xkb input xtest list misc fixes xfree86 check_LTLIBRARIES = libxservertest.la TESTS=$(noinst_PROGRAMS) @@ -23,6 +23,7 @@ xtest_LDADD=$(TEST_LDADD) list_LDADD=$(TEST_LDADD) misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) +xfree86_LDADD=$(TEST_LDADD) nodist_libxservertest_la_SOURCES = $(top_builddir)/hw/xfree86/sdksyms.c libxservertest_la_LIBADD = \ diff --git a/xorg-server/test/input.c b/xorg-server/test/input.c index 837ce49dc..b8dad1c60 100644 --- a/xorg-server/test/input.c +++ b/xorg-server/test/input.c @@ -1223,7 +1223,7 @@ static void dix_valuator_alloc(void) assert(v); assert(v->numAxes == num_axes); -#ifndef __i386__ +#if !defined(__i386__) && !defined(__sh__) /* must be double-aligned on 64 bit */ assert(((void*)v->axisVal - (void*)v) % sizeof(double) == 0); assert(((void*)v->axes - (void*)v) % sizeof(double) == 0); @@ -1234,6 +1234,169 @@ static void dix_valuator_alloc(void) free(v); } +static void dix_get_master(void) +{ + DeviceIntRec vcp, vck; + DeviceIntRec ptr, kbd; + DeviceIntRec floating; + SpriteInfoRec vcp_sprite, vck_sprite; + SpriteInfoRec ptr_sprite, kbd_sprite; + SpriteInfoRec floating_sprite; + + memset(&vcp, 0, sizeof(DeviceIntRec)); + memset(&vck, 0, sizeof(DeviceIntRec)); + memset(&ptr, 0, sizeof(DeviceIntRec)); + memset(&kbd, 0, sizeof(DeviceIntRec)); + memset(&floating, 0, sizeof(DeviceIntRec)); + + memset(&vcp_sprite, 0, sizeof(DeviceIntRec)); + memset(&vck_sprite, 0, sizeof(DeviceIntRec)); + memset(&ptr_sprite, 0, sizeof(DeviceIntRec)); + memset(&kbd_sprite, 0, sizeof(DeviceIntRec)); + memset(&floating_sprite, 0, sizeof(DeviceIntRec)); + + vcp.type = MASTER_POINTER; + vck.type = MASTER_KEYBOARD; + ptr.type = SLAVE; + kbd.type = SLAVE; + floating.type = SLAVE; + + vcp.spriteInfo = &vcp_sprite; + vck.spriteInfo = &vck_sprite; + ptr.spriteInfo = &ptr_sprite; + kbd.spriteInfo = &kbd_sprite; + floating.spriteInfo = &floating_sprite; + + vcp_sprite.paired = &vck; + vck_sprite.paired = &vcp; + ptr_sprite.paired = &vcp; + kbd_sprite.paired = &vck; + floating_sprite.paired = &floating; + + vcp_sprite.spriteOwner = TRUE; + floating_sprite.spriteOwner = TRUE; + + ptr.master = &vcp; + kbd.master = &vck; + + assert(GetPairedDevice(&vcp) == &vck); + assert(GetPairedDevice(&vck) == &vcp); + assert(GetMaster(&ptr, MASTER_POINTER) == &vcp); + assert(GetMaster(&ptr, MASTER_KEYBOARD) == &vck); + assert(GetMaster(&kbd, MASTER_POINTER) == &vcp); + assert(GetMaster(&kbd, MASTER_KEYBOARD) == &vck); + assert(GetMaster(&ptr, MASTER_ATTACHED) == &vcp); + assert(GetMaster(&kbd, MASTER_ATTACHED) == &vck); + + assert(GetPairedDevice(&floating) == &floating); + assert(GetMaster(&floating, MASTER_POINTER) == NULL); + assert(GetMaster(&floating, MASTER_KEYBOARD) == NULL); + assert(GetMaster(&floating, MASTER_ATTACHED) == NULL); + + assert(GetMaster(&vcp, POINTER_OR_FLOAT) == &vcp); + assert(GetMaster(&vck, POINTER_OR_FLOAT) == &vcp); + assert(GetMaster(&ptr, POINTER_OR_FLOAT) == &vcp); + assert(GetMaster(&kbd, POINTER_OR_FLOAT) == &vcp); + + assert(GetMaster(&vcp, KEYBOARD_OR_FLOAT) == &vck); + assert(GetMaster(&vck, KEYBOARD_OR_FLOAT) == &vck); + assert(GetMaster(&ptr, KEYBOARD_OR_FLOAT) == &vck); + assert(GetMaster(&kbd, KEYBOARD_OR_FLOAT) == &vck); + + assert(GetMaster(&floating, KEYBOARD_OR_FLOAT) == &floating); + assert(GetMaster(&floating, POINTER_OR_FLOAT) == &floating); +} + + +static void input_option_test(void) +{ + InputOption *list = NULL; + InputOption *opt; + const char *val; + + printf("Testing input_option list interface\n"); + + list = input_option_new(list, "key", "value"); + assert(list); + opt = input_option_find(list, "key"); + val = input_option_get_value(opt); + assert(strcmp(val, "value") == 0); + + list = input_option_new(list, "2", "v2"); + opt = input_option_find(list, "key"); + val = input_option_get_value(opt); + assert(strcmp(val, "value") == 0); + + opt = input_option_find(list, "2"); + val = input_option_get_value(opt); + assert(strcmp(val, "v2") == 0); + + list = input_option_new(list, "3", "v3"); + + /* search, delete */ + opt = input_option_find(list, "key"); + val = input_option_get_value(opt); + assert(strcmp(val, "value") == 0); + list = input_option_free_element(list, "key"); + opt = input_option_find(list, "key"); + assert(opt == NULL); + + opt = input_option_find(list, "2"); + val = input_option_get_value(opt); + assert(strcmp(val, "v2") == 0); + list = input_option_free_element(list, "2"); + opt = input_option_find(list, "2"); + assert(opt == NULL); + + opt = input_option_find(list, "3"); + val = input_option_get_value(opt); + assert(strcmp(val, "v3") == 0); + list = input_option_free_element(list, "3"); + opt = input_option_find(list, "3"); + assert(opt == NULL); + + /* list deletion */ + list = input_option_new(list, "1", "v3"); + list = input_option_new(list, "2", "v3"); + list = input_option_new(list, "3", "v3"); + input_option_free_list(&list); + + assert(list == NULL); + + list = input_option_new(list, "1", "v1"); + list = input_option_new(list, "2", "v2"); + list = input_option_new(list, "3", "v3"); + + /* value replacement */ + opt = input_option_find(list, "2"); + val = input_option_get_value(opt); + assert(strcmp(val, "v2") == 0); + input_option_set_value(opt, "foo"); + val = input_option_get_value(opt); + assert(strcmp(val, "foo") == 0); + opt = input_option_find(list, "2"); + val = input_option_get_value(opt); + assert(strcmp(val, "foo") == 0); + + /* key replacement */ + input_option_set_key(opt, "bar"); + val = input_option_get_key(opt); + assert(strcmp(val, "bar") == 0); + opt = input_option_find(list, "bar"); + val = input_option_get_value(opt); + assert(strcmp(val, "foo") == 0); + + /* value replacement in input_option_new */ + list = input_option_new(list, "bar", "foobar"); + opt = input_option_find(list, "bar"); + val = input_option_get_value(opt); + assert(strcmp(val, "foobar") == 0); + + input_option_free_list(&list); + assert(list == NULL); +} + + int main(int argc, char** argv) { dix_input_valuator_masks(); @@ -1249,6 +1412,8 @@ int main(int argc, char** argv) include_bit_test_macros(); xi_unregister_handlers(); dix_valuator_alloc(); + dix_get_master(); + input_option_test(); return 0; } diff --git a/xorg-server/test/list.c b/xorg-server/test/list.c index b101c7619..f7d7bffce 100644 --- a/xorg-server/test/list.c +++ b/xorg-server/test/list.c @@ -29,6 +29,7 @@ #include <list.h> #include <string.h> #include <assert.h> +#include <stdlib.h> struct parent { int a; @@ -161,6 +162,164 @@ test_list_for_each(void) } } +struct foo { + char a; + struct foo *next; + char b; +}; + +static void +test_nt_list_init(void) +{ + struct foo foo; + + foo.a = 10; + foo.b = 20; + nt_list_init(&foo, next); + + assert(foo.a == 10); + assert(foo.b == 20); + assert(foo.next == NULL); + assert(nt_list_next(&foo, next) == NULL); +} + +static void +test_nt_list_append(void) +{ + int i; + struct foo *foo = calloc(10, sizeof(struct foo)); + struct foo *item; + + for (item = foo, i = 1; i <= 10; i++, item++) + { + item->a = i; + item->b = i * 2; + nt_list_init(item, next); + + if (item != foo) + nt_list_append(item, foo, struct foo, next); + } + + /* Test using nt_list_next */ + for (item = foo, i = 1; i <= 10; i++, item = nt_list_next(item, next)) + { + assert(item->a = i); + assert(item->b = i * 2); + } + + /* Test using nt_list_for_each_entry */ + i = 1; + nt_list_for_each_entry(item, foo, next) { + assert(item->a = i); + assert(item->b = i * 2); + i++; + } + assert(i == 11); +} + +static void +test_nt_list_insert(void) +{ + int i; + struct foo *foo = calloc(10, sizeof(struct foo)); + struct foo *item; + + foo->a = 10; + foo->b = 20; + nt_list_init(foo, next); + + for (item = &foo[1], i = 9; i > 0; i--, item++) + { + item->a = i; + item->b = i * 2; + nt_list_init(item, next); + nt_list_insert(item, foo, struct foo, next); + } + + /* Test using nt_list_next */ + for (item = foo, i = 10; i > 0; i--, item = nt_list_next(item, next)) + { + assert(item->a = i); + assert(item->b = i * 2); + } + + /* Test using nt_list_for_each_entry */ + i = 1; + nt_list_for_each_entry(item, foo, next) { + assert(item->a = i); + assert(item->b = i * 2); + i++; + } + assert(i == 11); +} + +static void +test_nt_list_delete(void) +{ + int i = 1; + struct foo *list = calloc(10, sizeof(struct foo)); + struct foo *foo = list; + struct foo *item, *tmp; + struct foo *empty_list = foo; + + nt_list_init(empty_list, next); + nt_list_del(empty_list, empty_list, struct foo, next); + assert(!empty_list); + + for (item = foo, i = 1; i <= 10; i++, item++) + { + item->a = i; + item->b = i * 2; + nt_list_init(item, next); + + if (item != foo) + nt_list_append(item, foo, struct foo, next); + } + + i = 0; + nt_list_for_each_entry(item, foo, next) { + i++; + } + assert(i == 10); + + /* delete last item */ + nt_list_del(&foo[9], foo, struct foo, next); + i = 0; + nt_list_for_each_entry(item, foo, next) { + assert(item->a != 10); /* element 10 is gone now */ + i++; + } + assert(i == 9); /* 9 elements left */ + + /* delete second item */ + nt_list_del(foo->next, foo, struct foo, next); + assert(foo->next->a == 3); + + i = 0; + nt_list_for_each_entry(item, foo, next) { + assert(item->a != 10); /* element 10 is gone now */ + assert(item->a != 2); /* element 2 is gone now */ + i++; + } + assert(i == 8); /* 9 elements left */ + + item = foo; + /* delete first item */ + nt_list_del(foo, foo, struct foo, next); + assert(item != foo); + assert(item->next == NULL); + assert(foo->a == 3); + assert(foo->next->a == 4); + + nt_list_for_each_entry_safe(item, tmp, foo, next) { + nt_list_del(item, foo, struct foo, next); + } + + assert(!foo); + assert(!item); + + free(list); +} int main(int argc, char** argv) { @@ -169,5 +328,10 @@ int main(int argc, char** argv) test_list_del(); test_list_for_each(); + test_nt_list_init(); + test_nt_list_append(); + test_nt_list_insert(); + test_nt_list_delete(); + return 0; } diff --git a/xorg-server/test/xfree86.c b/xorg-server/test/xfree86.c new file mode 100644 index 000000000..7012e90c3 --- /dev/null +++ b/xorg-server/test/xfree86.c @@ -0,0 +1,81 @@ +/** + * Copyright © 2011 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <assert.h> + + +#include "xf86.h" + +static void +xfree86_option_list_duplicate(void) +{ + XF86OptionPtr options; + XF86OptionPtr duplicate; + const char *o1 = "foo", + *o2 = "bar", + *v1 = "one", + *v2 = "two"; + const char *o_null= "NULL"; + char *val1, *val2; + XF86OptionPtr a, b; + + duplicate = xf86OptionListDuplicate(NULL); + assert(!duplicate); + + options = xf86AddNewOption(NULL, o1, v1); + assert(options); + options = xf86AddNewOption(options, o2, v2); + assert(options); + options = xf86AddNewOption(options, o_null, NULL); + assert(options); + + duplicate = xf86OptionListDuplicate(options); + assert(duplicate); + + val1 = xf86CheckStrOption(options, o1, "1"); + val2 = xf86CheckStrOption(duplicate, o1, "2"); + + assert(strcmp(val1, v1) == 0); + assert(strcmp(val1, val2) == 0); + + val1 = xf86CheckStrOption(options, o2, "1"); + val2 = xf86CheckStrOption(duplicate, o2, "2"); + + assert(strcmp(val1, v2) == 0); + assert(strcmp(val1, val2) == 0); + + a = xf86FindOption(options, o_null); + b = xf86FindOption(duplicate, o_null); + assert(a && b); +} + +int main(int argc, char** argv) +{ + xfree86_option_list_duplicate(); + + return 0; +} diff --git a/xorg-server/xkb/xkbAccessX.c b/xorg-server/xkb/xkbAccessX.c index 12fe2a1f5..4115ff27d 100644 --- a/xorg-server/xkb/xkbAccessX.c +++ b/xorg-server/xkb/xkbAccessX.c @@ -124,15 +124,11 @@ AccessXKeyboardEvent(DeviceIntPtr keybd, Bool isRepeat) { DeviceEvent event; - memset(&event, 0, sizeof(DeviceEvent)); - event.header = ET_Internal; + + init_device_event(&event, keybd, GetTimeInMillis()); event.type = type; event.detail.key = keyCode; - event.time = GetTimeInMillis(); - event.length = sizeof(DeviceEvent); event.key_repeat = isRepeat; - event.sourceid = keybd->id; - event.deviceid = keybd->id; if (xkbDebugFlags&0x8) { DebugF("[xkb] AXKE: Key %d %s\n", keyCode, |